class Controller: def __init__(self): self.qt_app = QApplication(sys.argv) self.model = Model() self.view = View() self.view.button.clicked.connect(self.update_model) self.model.signal.connect(self.update_view) signal.signal(signal.SIGINT, self.keyboardInterruptHandler) self.time = QTime() timer = QTimer() timer.timeout.connect(lambda: None) timer.start(100) self.qt_app.exec() def update_model(self): self.time.start() self.model.setdata(self.view.getdata()) def update_view(self): print("--- DONE IN {}ms ---".format(self.time.elapsed())) self.time.restart() self.view.setdata(self.model.getdata()) def keyboardInterruptHandler(self, signal, frame): self.qt_app.exit()
def on_btn2_1_click(self): video = cv2.VideoCapture('D:/data/bgSub.mp4') if not video.isOpened(): print('video not found') return w = None subtractor = cv2.createBackgroundSubtractorMOG2()#detectShadows=False) t = QTime() t.start() while video.isOpened(): ret, frame = video.read() if ret: fg = subtractor.apply(frame) if w is None: w = MultiImageWindow( title='2.1 Background Subtraction', images=[frame, fg]) w.show() self.addWidget(w) else: w.setImage(frame, 0) w.setImage(fg, 1) w.update() t.restart() while t.elapsed() < 33: QApplication.processEvents() else: break video.release()
class Example(QWidget): def __init__(self, vehicles_N, vehicles_W, vehicles_E, sendData_1, sendData_2, sendData_3): super().__init__() self.vehicles_N = vehicles_N self.vehicles_W = vehicles_W self.vehicles_E = vehicles_E self.sendData_1 = sendData_1 self.sendData_2 = sendData_2 self.sendData_3 = sendData_3 self.my_result = 0 self.t_t = 0 self.initUI() self.timer = QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000 / 60) #一秒間隔で更新 self.t = QTime() self.t.start() self.show() def initUI(self): self.setGeometry(300, 300, 600, 600) self.setWindowTitle("Koku's Simulation") self.ti = 0 self.beze_t = [] self.r = [] self.up_left_x = [] self.up_left_y = [] self.down_left_x = [] self.down_left_y = [] self.up_right_x = [] self.up_right_y = [] self.down_right_x = [] self.down_right_y = [] for i in range(10): self.beze_t.append(0) self.r.append(0) self.up_left_x.append(0) self.up_left_y.append(0) self.down_left_x.append(0) self.down_left_y.append(0) self.up_right_x.append(0) self.up_right_y.append(0) self.down_right_x.append(0) self.down_right_y.append(0) self.single_0_0 = True self.single_0_1 = True self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] self.grid = {} for i in range(270, 330, 10): for j in range(270, 330, 10): self.grid[(i, j)] = True def paintEvent(self, e): self.t_t += 1 qp = QPainter(self) self.drawLines(qp) #self.drawSignals_0(qp) self.drawVehicles(qp) def drawLines(self, qp): # print(self.t.elapsed()) pen = QPen(Qt.black, 2, Qt.SolidLine) pen_dash = QPen(Qt.black, 2, Qt.DotLine) # Vertical qp.setPen(pen) qp.drawLine(270, 0, 270, 600) # with grids ################## # qp.drawLine(280, 0, 280, 600) # qp.drawLine(290, 0, 290, 600) # qp.drawLine(300, 0, 300, 600) # qp.drawLine(310, 0, 310, 600) # qp.drawLine(320, 0, 320, 600) # with grids ################## qp.drawLine(330, 0, 330, 600) qp.drawLine(300, 0, 300, 270) qp.drawLine(300, 330, 300, 600) qp.setPen(pen_dash) qp.drawLine(280, 330, 280, 600) qp.drawLine(290, 330, 290, 600) qp.drawLine(310, 330, 310, 600) qp.drawLine(320, 330, 320, 600) qp.drawLine(280, 0, 280, 270) qp.drawLine(290, 0, 290, 270) qp.drawLine(310, 0, 310, 270) qp.drawLine(320, 0, 320, 270) # Tropical qp.setPen(pen) qp.drawLine(0, 270, 600, 270) # with grids ################## # qp.drawLine(0, 280, 600, 280) # qp.drawLine(0, 290, 600, 290) # qp.drawLine(0, 300, 600, 300) # qp.drawLine(0, 310, 600, 310) # qp.drawLine(0, 320, 600, 320) # with grids ################## qp.drawLine(0, 330, 600, 330) qp.drawLine(0, 300, 270, 300) qp.drawLine(330, 300, 600, 300) qp.setPen(pen_dash) qp.drawLine(0, 280, 270, 280) qp.drawLine(0, 290, 270, 290) qp.drawLine(0, 310, 270, 310) qp.drawLine(0, 320, 270, 320) qp.drawLine(330, 280, 600, 280) qp.drawLine(330, 290, 600, 290) qp.drawLine(330, 310, 600, 310) qp.drawLine(330, 320, 600, 320) def drawSignals_0(self, qp): #print(self.t.elapsed()) if 1000 < self.t.elapsed() < 2000: qp.setPen(Qt.black) qp.setBrush(Qt.red) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = False self.single_0_1 = True else: qp.setPen(Qt.black) qp.setBrush(Qt.green) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = True self.single_0_1 = False def coordinate_up_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_up_left_y(self, po_y): return po_y def coordinate_up_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_up_right_y(self, po_y): return po_y def coordinate_down_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_down_left_y(self, po_y, r): return po_y + 5 * math.sin(math.radians(r)) + 10 * math.cos( math.radians(r)) def coordinate_down_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_down_right_y(self, po_y, r): return po_y + 10 * math.sin(math.radians(r)) + 5 * math.cos( math.radians(r)) def propose(self, veh_id, current, origin, destination, speed, current_time, pattern, sendData): server_address = ('localhost', 6789) max_size = 4096 print('Starting the client at', datetime.now()) client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sendData_1["pattern"] = pattern current_position = list(current) print('++++++++++++++++++++++++++++++++++++++') self.sendData_1["origin"] = list(origin) self.sendData_1["destination"] = list(destination) self.sendData_1["speed"] = speed # sendData_1: veh info and current Total_time dictMerge = dict({"time_step": current_time}, **sendData) dictMerge = dict({"current_position": current_position}, **dictMerge) mes = bytes(json.dumps(dictMerge), encoding='utf-8') print(dictMerge) client.sendto(mes, server_address) data, server = client.recvfrom(max_size) data = data.decode('utf-8') recData = json.loads(data) print('At', datetime.now(), server, 'said', recData) client.close() self.my_result = recData['result'] return self.my_result # def propose_pattern_3(self, veh_id, current, origin, destination, speed, current_time, pattern): # server_address = ('localhost', 6789) # max_size = 4096 # # print('Starting the client at', datetime.now()) # # client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # # self.sendData_3["pattern"] = pattern # current_position = list(current) # print('++++++++++++++++++++++++++++++++++++++') # self.sendData_3["origin"] = list(origin) # self.sendData_3["destination"] = list(destination) # self.sendData_3["speed"] = speed # # # sendData_1: veh info and current Total_time # dictMerge = dict({"time_step": current_time}, **self.sendData_3["vehicle"][veh_id]) # dictMerge = dict({"current_position": current_position}, **dictMerge) # mes = bytes(json.dumps(dictMerge), encoding='utf-8') # print(dictMerge) # # client.sendto(mes, server_address) # data, server = client.recvfrom(max_size) # # data = data.decode('utf-8') # recData = json.loads(data) # print('At', datetime.now(), server, 'said', recData) # client.close() # self.my_result = recData['result'] # # return self.my_result def drawVehicles(self, qp): qp.setPen(Qt.black) qp.setBrush(Qt.green) #qp.drawRect(310, 310, 5, 10) # Vehicles Pattern2(from N5 to S5) for i, veh in enumerate(vehicles_N): if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_N: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) else: # Just before intersection if veh.getPosition().y + veh.getSpeed( ).y > 260 and veh.getPosition().y <= 260: # Try to make a reservation from IM. If false, then stop before entering. if self.propose(i, (vehicles_N[i].getPosition().x, vehicles_N[i].getPosition().y), (313, 270), (313, 330), veh.getSpeed().y, self.t_t, 2, self.sendData_2["vehicle"][i]): # if True: self.vehicles_N[i].getPosition( ).y += self.vehicles_N[i].getSpeed().y if self.vehicles_N[i].getPosition().y > 600: self.vehicles_N[i].getPosition().y = 0 qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) else: qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) else: self.vehicles_N[i].getPosition( ).y += self.vehicles_N[i].getSpeed().y if self.vehicles_N[i].getPosition().y > 600: self.vehicles_N[i].getPosition().y = 0 qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) for i in range(5): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) # Vehicles Pattern1(from W1 to S6) for i, veh in enumerate(vehicles_W): # Check if there are vehicles ahead. If true, stop if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_W: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # Make the room not available for other vehicles for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Move forward else: # Just before the intersection if veh.getPosition().x + 10 + veh.getSpeed( ).x > 270 and veh.getPosition().x <= 270 - 10: # Check traffic signal. True, then stop before entering. if not self.propose( i, (veh.getPosition().x, veh.getPosition().y), (270, 273), (330, 330), veh.getSpeed().x, self.t_t, 1, self.sendData_1["vehicle"][i]): print("False", (veh.getPosition().x, veh.getPosition().y)) qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Enter intersection else: print("True", (veh.getPosition().x, veh.getPosition().y)) veh.getPosition().x += veh.getSpeed().x qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) else: # Already in the intersection if 270 < veh.getPosition().x < 328 and veh.getPosition( ).y < 330: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) # Calculate rotation angle if ((veh.getPosition().x - 270 + veh.getSpeed().x) / 60) * 90 > 15: self.r[i] = ((veh.getPosition().x - 270 + veh.getSpeed().x) / 60) * 90 qp.rotate(self.r[i]) else: self.r[i] = 0 qp.rotate(self.r[i]) qp.translate(-veh.getPosition().x, -veh.getPosition().y) # Calculate trajectory by using Bezier Curve x = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 332 + pow( self.beze_t[i] / 60, 2) * 332 y = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 273 + pow( self.beze_t[i] / 60, 2) * 332 veh.setPosition(Position(x, y)) self.beze_t[i] += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) qp.restore() # Calculate the big Square's coordinate self.up_left_x[i] = self.coordinate_up_left_x( veh.getPosition().x, self.r[i]) self.up_left_y[i] = self.coordinate_up_left_y( veh.getPosition().y) self.down_left_x[i] = self.coordinate_down_left_x( veh.getPosition().x, self.r[i]) self.down_left_y[i] = self.coordinate_down_left_y( veh.getPosition().y, self.r[i]) self.up_right_x[i] = self.coordinate_up_right_x( veh.getPosition().x, self.r[i]) self.up_right_y[i] = self.coordinate_up_right_y( veh.getPosition().y) self.down_right_x[i] = self.coordinate_down_right_x( veh.getPosition().x, self.r[i]) self.down_right_y[i] = self.coordinate_down_right_y( veh.getPosition().y, self.r[i]) # Already left intersection elif 328 <= veh.getPosition().x and veh.getPosition( ).y < 600: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) qp.rotate(90) qp.translate(-veh.getPosition().x, -veh.getPosition().y) veh.getPosition().y += veh.getSpeed().x qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x, veh.getPosition().y - j)) qp.restore() # Already left screen elif veh.getPosition().y >= 600: veh.getPosition().x = 0 veh.getPosition().y = 273 self.beze_t[i] = 0 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x, veh.getPosition().y - j)) # Move horizontal direction(across X_axis) else: veh.getPosition().x += veh.getSpeed().x qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Vehicle Pattern3(From E4 to W4) if 330 <= vehicles_E[0].getPosition().x and vehicles_E[0].getPosition( ).x - vehicles_E[0].getSpeed().x < 330: if self.propose( 0, (vehicles_E[0].getPosition().x, vehicles_E[0].getPosition().y), (330, 302), (270, 302), veh.getSpeed().x, self.t_t, 3, self.sendData_3["vehicle"][0]): self.vehicles_E[0].getPosition( ).x -= self.vehicles_E[0].getSpeed().x if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) else: qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) else: self.vehicles_E[0].getPosition().x -= self.vehicles_E[0].getSpeed( ).x if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] self.ti += 10 if self.ti > 700: self.ti = 0 # print(self.t.elapsed()) self.t.restart()
class Lindworm(QMainWindow): def __init__(self, dir: str, parent: object = None) -> None: super(Lindworm, self).__init__(parent) loadUi(pjoin(dir, "res", "lindworm.ui"), self) self.setWindowIcon(QIcon(pjoin(dir, "res", "icon.png"))) # This is where all the objects are handled (drawn, updated, moved, painted, etc.) self.canvas = QGraphicsScene(self) # Use all the QGraphicsView area self.canvas.setSceneRect(0, 0, self.graphicsView.width(), self.graphicsView.height()) self.canvas.setBackgroundBrush( QBrush(QColor(52, 56, 56), Qt.SolidPattern)) self.graphicsView.setScene(self.canvas) # Application variables self.playing = False # Is the player playing? (obviously) self.timer = QBasicTimer( ) # Used for controlling the game speed, and the canvas update self.speed = 100 # Refresh rate which the game is updated (in milliseconds, # the greater it is, the slower is refresh) self.particleSize = 10 # Particle's size of the snake, food, border, ... (scale?) self.score = 0 # Keep track of the user's score self.playtime = QTime( ) # Keep track of the play time, uses later to increase the game speed self.snake = None self.food = None self.special = None self.drawBorder() self.centerOnScreen() self.show() # ####### Application Methods def startGame(self) -> None: """ Starts a New Game every time the user press [Enter, Return] if a game has not started yet """ self.playing = True # Reset the score self.score = 0 self.scoreLabel.setText(str(self.score)) # Start counting the time and the timer which controlls the game cycle self.speed = 100 self.playtime.start() self.timer.start(self.speed, Qt.PreciseTimer, self) # Check if there is a snake drawn on the canvas if self.snake is not None and self.snake in self.canvas.items(): self.canvas.removeItem(self.snake) # The same for the food and special food if self.food is not None and self.food in self.canvas.items(): self.canvas.removeItem(self.food) if self.special is not None and self.special in self.canvas.items(): self.canvas.removeItem(self.special) # Add the new Snake object to the canvas self.snake = Snake(self) self.canvas.addItem(self.snake) # Call the function to add a piece of Food self.addFood() def endGame(self) -> None: """ Handles the event when the Snake dies """ self.playing = False # Show the user the final score point = "point" if self.score == 1 else "points" self.scoreLabel.setText("Game Over. You scored <b>%d</b> %s" % (self.score, point)) # Stop the timer self.timer.stop() # Animate the Window self.shakeIt() def addFood(self, special: bool = False) -> None: """ Add a piece of Food to the canvas """ food = None # Check that the food doesn't spawns inside the snake's body while food is None: food = Food(self) position = [food.x(), food.y()] # If it's inside the body, try again if position in self.snake.body: food = None if special: self.special = food self.special.changeBrush() else: self.food = food self.canvas.addItem(food) def updateScore(self, points: int) -> None: self.score += points self.scoreLabel.setText(str(self.score)) # ####### QMainWindow events def closeEvent(self, event: QCloseEvent) -> None: """ Always remove junk when closing an application """ # Stop the Timer if it's active if self.timer.isActive(): self.timer.stop() # Continue with the closing event event.accept() def keyPressEvent(self, event: QKeyEvent) -> None: """ Listen to the user's input """ # Enter is the key located in the keypad, usually denoted by the text "Intro" # Return is the big key we usually use to create a break in a sentence start = [Qt.Key_Return, Qt.Key_Enter] # Game can be played using Arrow keys and WASD directions = [ Qt.Key_Left, Qt.Key_A, Qt.Key_Right, Qt.Key_D, Qt.Key_Up, Qt.Key_W, Qt.Key_Down, Qt.Key_S ] # Starts a new game if not already playing if not self.playing and event.key() in start: self.startGame() # Change the Snake's movement direction if self.playing and event.key() in directions: self.snake.changeDirection(event.key()) def timerEvent(self, event: QTimerEvent) -> None: """ In charge of, in this case, update the game and check the conditions to continue playing, grow, spawn food and special item """ # Check if the event if from the self.timer if event.timerId() is self.timer.timerId(): self.snake.update() # Add a piece of Special Food every 15 points if self.score % 15 == 0 and self.score != 0 and self.special is None: self.addFood(True) # Increase the movement speed of the Snake every 60 seconds if self.playtime.elapsed() > 60000: self.playtime.restart() self.speed -= 10 # Stop and start the timer, there is no method timer.setTime or # the like for changing the timer's speed of refresh self.timer.stop() self.timer.start(self.speed, Qt.PreciseTimer, self) # Check if the Snake ate the food if self.snake.ateFood(self.food): self.updateScore(1) self.addFood() # Same process for the Special food if self.snake.ateFood(self.special): self.updateScore(5) self.special = None # Check if Snake is out of bounds, or its head collided with # its body if self.snake.outOfBounds() or self.snake.headInsideOfTail(): self.endGame() else: super(Lindworm, self).timerEvent(event) # ####### "Beautifying" methods (graphics-wise) def drawBorder(self) -> None: """ Draw a decorative border in the perimeter of the QGraphicsView """ # Remove the outline outline = QPen(Qt.NoPen) # Change the background color for the object being drawn background = QBrush(QColor(0, 95, 107), Qt.Dense3Pattern) # [0, 10, 20, 30, ... , self.canvas.width()] with particle size set to 10 topBottom = range(0, int(self.canvas.width()), self.particleSize) # [10, 20, 30, 40, ... , self.canvas,height() - 10] with particle size set to 10 leftRight = range(self.particleSize, int(self.canvas.height()) - self.particleSize, self.particleSize) size = self.particleSize width = self.canvas.width() height = self.canvas.height() # Top, Bottom, Left, Right borders (in that order) areas = [ QRectF(0, 0, width, size), QRectF(0, height - size, width, size), QRectF(0, size, size, height - size * 2), QRectF(width - size, size, size, height - size * 2) ] for area in areas: self.canvas.addRect(area, outline, background) def shakeIt(self) -> None: """ Animate the Position of the Window when the Snake dies a horrible death due to the user's fault. In this case, the use of setStartValue and setEndValue cannot be implemented due to the fact that the initial and end position of the window are the same, hence the multiple calls of setKeyValueAt. """ self.animation = QPropertyAnimation(self, QByteArray().append("pos")) # Save the window's original position origin = self.pos() # Amount of pixels that the window is going to be moved offset = 40 self.animation.setKeyValueAt(0.0, QPointF(origin.x(), origin.y())) self.animation.setKeyValueAt(0.3, QPointF(origin.x() - offset, origin.y())) self.animation.setKeyValueAt(0.6, QPointF(origin.x() + offset, origin.y())) self.animation.setKeyValueAt(1.0, QPointF(origin.x(), origin.y())) # Duration of the animation, in milliseconds (1s = 1000ms) self.animation.setDuration(1000) # QEasingCurve.InOutElastic is a type of animation path self.animation.setEasingCurve(QEasingCurve.InOutElastic) # Start and Delete the animation when done self.animation.start(QAbstractAnimation.DeleteWhenStopped) def centerOnScreen(self) -> None: """ Centers the window on the screen keeping in mind the available space for the window to show """ frameGeometry = self.frameGeometry() centerPoint = QDesktopWidget().availableGeometry().center() frameGeometry.moveCenter(centerPoint) self.move(frameGeometry.topLeft())
class QGame(TabGame): # widget type # SHADOW = range(2) mouseMovePos = None offset_x = offset_y = 0 winner = True thread = None total_score = 0 def __init__(self, parent, chess_game=None, caption=None): super().__init__(parent, caption) self.boardWidget.addMoveListener(self) if chess_game == None: chess_game = chess.pgn.Game() self.board_type = 1 self.boardWidget.board_type = 1 else: self.board_type = 2 self.boardWidget.board_type = 2 self.node = chess_game self.board = chess_game.board() self.last_move = None result = chess_game.headers['Result'] self.flip_board = False if result == '0-1': self.winner = False self.flip_board = True self.boardWidget.setBoard(self.board, self.flip_board) self.can_move = self.board.turn == self.winner if not self.can_move: game_move = self.get_next_game_move() if game_move: self.parent.add_message('Opponent move: ' + self.board.san(game_move)) self.make_move(game_move) parent.game_state_changed(self) self.parent.add_message('**** Make move for ' + ('white' if self.board.turn else 'black')) self.timer = QTime() self.timer.start() # moves = game.main_line() # print(self.board.variation_san(moves)) def elapsed(self): return self.timer.elapsed() ''' def paintEvent(self, e): painter = QPainter() painter.begin(self) # paint board painter.drawPixmap(0, self.label_caption.height(), self.width, self.height, self.board_map) # paint last move if self.last_move: x = self.cx * ((7 - chess.square_file(self.last_move.from_square)) if self.flip_board else chess.square_file(self.last_move.from_square)) y = self.cy * (chess.square_rank(self.last_move.from_square) if self.flip_board else (7 - chess.square_rank(self.last_move.from_square))) + self.label_caption.height() painter.drawRect(QRectF(x, y, self.cx, self.cy)) x = self.cx * ((7 - chess.square_file(self.last_move.to_square)) if self.flip_board else chess.square_file(self.last_move.to_square)) y = self.cy * (chess.square_rank(self.last_move.to_square) if self.flip_board else (7 - chess.square_rank(self.last_move.to_square))) + self.label_caption.height() painter.drawRect(QRectF(x, y, self.cx, self.cy)) try: # paint pieces self.paint_pieces(self.board, self.flip_board) except Exception as ex: print(ex) painter.end() ''' def get_next_game_move(self): if len(self.node.variations) < 1: return None next_node = self.node.variations[0] self.node = next_node return next_node.move def get_last_move(self): lm = None try: lm = self.board.peek() except: pass return lm def compare_user_move_with_game(self, move): game_move = self.get_next_game_move() if game_move is None: return move_text = self.board.san(move) self.parent.add_message('Your move: ' + move_text + ', Game move: ' + self.board.san(game_move)) is_book_move = self.parent.is_book_move(self.board, move) if is_book_move: opening_name = self.parent.get_opening_name(self.board) self.parent.add_message(move_text + ' (Book move ' + opening_name + ')') if move != game_move and not is_book_move: board_copy = self.board.copy() self.thread = Thread(target=self.compare_moves, args=(board_copy, move, game_move)) self.thread.start() self.make_move(game_move) def make_move(self, move): self.last_move = move self.board.push(move) self.can_move = self.board.turn == self.winner if self.board_type == 2 else True self.parent.game_state_changed(self) def compare_moves(self, board, user_move, game_move): # evaluate move score evaluation = self.parent.evaluate_moves(board, [user_move, game_move]) score_diff = evaluation[user_move] - evaluation[game_move] self.parent.add_message('Move score (' + board.san(user_move) + ' vs ' + board.san(game_move) + '): ' + str(score_diff)) self.total_score += score_diff self.parent.add_message('Game score: ' + str(self.total_score)) def evaluate(self, board, move): # evaluate move score evaluation = self.parent.evaluate_board(board)[0] self.parent.add_message('Position Evaluation (' + move + ') ' + str(evaluation)) # process user move def userMoved(self, uci_move): move = chess.Move.from_uci(uci_move) # is it a legal move? if move in self.board.legal_moves: if self.board_type == 2: self.compare_user_move_with_game(move) # make opponents move if not self.can_move: # make the next game move as well game_move = self.get_next_game_move() if game_move is None: return self.parent.add_message('Opponent move: ' + self.board.san(game_move)) self.make_move(game_move) self.parent.add_message('**** Make move for ' + ( 'white' if self.board.turn else 'black')) self.timer.restart() else: self.make_move(move)
class Example(QWidget): def __init__(self, vehicles_N, vehicles_W, vehicles_E, sendData): super().__init__() self.vehicles_N = vehicles_N self.vehicles_W = vehicles_W self.vehicles_E = vehicles_E self.sendData = sendData self.my_result = 0 self.initUI() self.timer = QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000/60)#一秒間隔で更新 self.t = QTime() self.t.start() self.show() def initUI(self): self.setGeometry(300, 300, 600, 600) self.setWindowTitle("Koku's Simulation") self.ti = 0 self.beze_t = [] self.r = [] self.up_left_x = [] self.up_left_y = [] self.down_left_x = [] self.down_left_y = [] self.up_right_x = [] self.up_right_y = [] self.down_right_x = [] self.down_right_y = [] for i in range(10): self.beze_t.append(0) self.r.append(0) self.up_left_x.append(0) self.up_left_y.append(0) self.down_left_x.append(0) self.down_left_y.append(0) self.up_right_x.append(0) self.up_right_y.append(0) self.down_right_x.append(0) self.down_right_y.append(0) self.single_0_0 = True self.single_0_1 = True self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] self.grid = {} for i in range(270, 330, 10): for j in range(270, 330, 10): self.grid[(i, j)] = True def paintEvent(self, e): #print("!") qp = QPainter(self) self.drawLines(qp) self.drawSignals_0(qp) self.drawVehicles(qp) def drawLines(self, qp): # print(self.t.elapsed()) pen = QPen(Qt.black, 2, Qt.SolidLine) pen_dash = QPen(Qt.black, 2, Qt.DotLine) # Vertical qp.setPen(pen) qp.drawLine(270, 0, 270, 600) # with grids ################## # qp.drawLine(280, 0, 280, 600) # qp.drawLine(290, 0, 290, 600) # qp.drawLine(300, 0, 300, 600) # qp.drawLine(310, 0, 310, 600) # qp.drawLine(320, 0, 320, 600) # with grids ################## qp.drawLine(330, 0, 330, 600) qp.drawLine(300, 0, 300, 270) qp.drawLine(300, 330, 300, 600) qp.setPen(pen_dash) qp.drawLine(280, 330, 280, 600) qp.drawLine(290, 330, 290, 600) qp.drawLine(310, 330, 310, 600) qp.drawLine(320, 330, 320, 600) qp.drawLine(280, 0, 280, 270) qp.drawLine(290, 0, 290, 270) qp.drawLine(310, 0, 310, 270) qp.drawLine(320, 0, 320, 270) # Tropical qp.setPen(pen) qp.drawLine(0, 270, 600, 270) # with grids ################## # qp.drawLine(0, 280, 600, 280) # qp.drawLine(0, 290, 600, 290) # qp.drawLine(0, 300, 600, 300) # qp.drawLine(0, 310, 600, 310) # qp.drawLine(0, 320, 600, 320) # with grids ################## qp.drawLine(0, 330, 600, 330) qp.drawLine(0, 300, 270, 300) qp.drawLine(330, 300, 600, 300) qp.setPen(pen_dash) qp.drawLine(0, 280, 270, 280) qp.drawLine(0, 290, 270, 290) qp.drawLine(0, 310, 270, 310) qp.drawLine(0, 320, 270, 320) qp.drawLine(330, 280, 600, 280) qp.drawLine(330, 290, 600, 290) qp.drawLine(330, 310, 600, 310) qp.drawLine(330, 320, 600, 320) def drawSignals_0(self, qp): #print(self.t.elapsed()) if 1000 < self.t.elapsed() < 2000: qp.setPen(Qt.black) qp.setBrush(Qt.red) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = False self.single_0_1 = True else: qp.setPen(Qt.black) qp.setBrush(Qt.green) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = True self.single_0_1 = False def coordinate_up_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_up_left_y(self, po_y): return po_y def coordinate_up_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_up_right_y(self, po_y): return po_y def coordinate_down_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_down_left_y(self, po_y, r): return po_y + 5 * math.sin(math.radians(r)) + 10 * math.cos(math.radians(r)) def coordinate_down_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_down_right_y(self, po_y, r): return po_y + 10 * math.sin(math.radians(r)) + 5 * math.cos(math.radians(r)) def propose(self, veh_id): server_address = ('localhost', 6789) max_size = 4096 print('Starting the client at', datetime.now()) client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) mes = bytes(json.dumps(self.sendData[veh_id]), encoding='utf-8') client.sendto(mes, server_address) data, server = client.recvfrom(max_size) data = data.decode('utf-8') recData = json.loads(data) print('At', datetime.now(), server, 'said', recData) client.close() print('!!!!!!!', recData['result']) self.my_result = recData['result'] return self.my_result def aaa(self, veh_id): if veh_id > 5: return 1 else: return 0 def drawVehicles(self, qp): qp.setPen(Qt.black) qp.setBrush(Qt.green) qp.drawRect(310, 310, 5, 10) for i in range(10): if self.propose(i): print('?????????????') #qp.drawRect(300, 300, 5, 10) else: print('!!!!!!!!!!!!!') #qp.drawRect(400, 400, 5, 10) # # Vehicles from North # for i, veh in enumerate(vehicles_N): # if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_N: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # else: # if veh.getPosition().y + veh.getSpeed().y > 260 and veh.getPosition().y <= 260: # if self.single_0_1: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # else: # if veh.getPosition().y <= 270: # if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: # # veh.getPosition().y += veh.getSpeed().y # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # self.grid[(veh.getPosition().x // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False # else: # try: # if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: # # self.vehicles_N[i].getPosition().y += veh.getSpeed().y # # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False # # if self.vehicles_N[i].getPosition().y > 600: # self.vehicles_N[i].getPosition().y = 0 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # # except KeyError: # self.vehicles_N[i].getPosition().y += veh.getSpeed().y # # if self.vehicles_N[i].getPosition().y > 600: # self.vehicles_N[i].getPosition().y = 0 # # qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) # # else: # # print(self.single_0_1) # veh.getPosition().y += veh.getSpeed().y # if veh.getPosition().y > 600: # veh.getPosition().y = 0 # # print(self.t.elapsed()) # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # # #print(self.collision_check) # # # # # Vehicles from West # for i, veh in enumerate(vehicles_W): # # Check if there are vehicles ahead. If true, stop # if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_W: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # # Make the room not available for other vehicles # for j in range(11): # self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # # Move forward # else: # # Just before the intersection # if veh.getPosition().x + 10 + 2 > 270 and veh.getPosition().x <= 270 - 10: # # Check traffic signal. True, then stop before entering. # if self.single_0_0: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # # Enter intersection # else: # veh.getPosition().x += 2 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # # # Light up the grids in the intersection # # Up left # if (veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: # self.grid[(veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Up right # if ((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: # self.grid[((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Down left # if (veh.getPosition().x // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: # self.grid[(veh.getPosition().x // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Down right # if ((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: # self.grid[((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Already in the intersection # else: # if 270 < veh.getPosition().x < 328 and veh.getPosition().y < 330: # qp.save() # qp.translate(veh.getPosition().x, veh.getPosition().y) # # # Calculate rotation angle # if (((veh.getPosition().x - 270 + 3) / 60) * 90 > 15): # self.r[i] = ((veh.getPosition().x - 270 + 3) / 60) * 90 # qp.rotate(self.r[i]) # else: # self.r[i] = 0 # qp.rotate(self.r[i]) # qp.translate(-veh.getPosition().x, -veh.getPosition().y) # # # Calculate trajectory by using Bezier Curve # x = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( # 1 - self.beze_t[i] / 60) * 332 + pow( # self.beze_t[i] / 60, 2) * 332 # y = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( # 1 - self.beze_t[i] / 60) * 273 + pow( # self.beze_t[i] / 60, 2) * 332 # veh.setPosition(Position(x, y)) # # self.beze_t[i] += 2 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # qp.restore() # # # Calculate the big Square's coordinate # self.up_left_x[i] = self.coordinate_up_left_x(veh.getPosition().x, self.r[i]) # self.up_left_y[i] = self.coordinate_up_left_y(veh.getPosition().y) # self.down_left_x[i] = self.coordinate_down_left_x(veh.getPosition().x, self.r[i]) # self.down_left_y[i] = self.coordinate_down_left_y(veh.getPosition().y, self.r[i]) # self.up_right_x[i] = self.coordinate_up_right_x(veh.getPosition().x, self.r[i]) # self.up_right_y[i] = self.coordinate_up_right_y(veh.getPosition().y) # self.down_right_x[i] = self.coordinate_down_right_x(veh.getPosition().x, self.r[i]) # self.down_right_y[i] = self.coordinate_down_right_y(veh.getPosition().y, self.r[i]) # # # Up left # if (self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10) in self.grid: # self.grid[(self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10)] = False # # print('success') # # # Up right # if ((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10) in self.grid: # self.grid[((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10)] = False # # print('success') # # # Down left # if (self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10) in self.grid: # self.grid[(self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10)] = False # # print('success') # # # Down right # if ((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10) in self.grid: # self.grid[((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10)] = False # # print('success') # # # Already left intersection # elif 328 <= veh.getPosition().x and veh.getPosition().y < 600: # qp.save() # qp.translate(veh.getPosition().x, veh.getPosition().y) # qp.rotate(90) # qp.translate(-veh.getPosition().x, -veh.getPosition().y) # veh.getPosition().y += 2 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x, veh.getPosition().y - j)) # qp.restore() # # # Already left screen # elif veh.getPosition().y >= 600: # veh.getPosition().x = 0 # veh.getPosition().y = 273 # self.beze_t[i] = 0 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x, veh.getPosition().y - j)) # # # Move horizontal direction(across X_axis) # else: # veh.getPosition().x += 2 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) # for j in range(11): # self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # # # Vehicle2 # # if self.single_0_0: # # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # else: # try: # if self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)]: # # self.vehicles_E[0].getPosition().x -= 3 # # if self.vehicles_E[0].getPosition().x < 0: # self.vehicles_E[0].getPosition().x = 600 # # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # else: # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # except KeyError: # self.vehicles_E[0].getPosition().x -= 3 # # if self.vehicles_E[0].getPosition().x < 0: # self.vehicles_E[0].getPosition().x = 600 # # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # self.collision_check = [] # self.collision_check_N = [] # self.collision_check_S = [] # self.collision_check_W = [] # self.collision_check_E = [] # # # for i in range(270, 330, 10): # for j in range(270, 330, 10): # self.grid[(i, j)] = True # # self.ti += 10 if self.ti > 700: self.ti = 0 # print(self.t.elapsed()) self.t.restart()
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _text_queue: A deque of (error, text) tuples to be displayed. error: True if message is an error, False otherwise _text_pop_timer: A Timer displaying the error messages. _stopwatch: A QTime for the last displayed message. _timer_was_active: Whether the _text_pop_timer was active before hiding the command widget. _previous_widget: A PreviousWidget member - the widget which was displayed when an error interrupted it. _win_id: The window ID the statusbar is associated with. Class attributes: _error: If there currently is an error, accessed through the error property. For some reason we need to have this as class attribute so pyqtProperty works correctly. _prompt_active: If we're currently in prompt-mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _insert_active: If we're currently in insert mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move the the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _error = False _prompt_active = False _insert_active = False STYLESHEET = """ QWidget#StatusBar { {{ color['statusbar.bg'] }} } QWidget#StatusBar[insert_active="true"] { {{ color['statusbar.bg.insert'] }} } QWidget#StatusBar[prompt_active="true"] { {{ color['statusbar.bg.prompt'] }} } QWidget#StatusBar[error="true"] { {{ color['statusbar.bg.error'] }} } QLabel, QLineEdit { {{ color['statusbar.fg'] }} {{ font['statusbar'] }} } """ def __init__(self, win_id, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._option = None self._stopwatch = QTime() self._hbox = QHBoxLayout(self) self._hbox.setContentsMargins(0, 0, 0, 0) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self._timer_was_active = False self._text_queue = collections.deque() self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') self._text_pop_timer.timeout.connect(self._pop_text) self.set_pop_timer_interval() objreg.get('config').changed.connect(self.set_pop_timer_interval) self.prompt = prompt.Prompt(win_id) self._stack.addWidget(self.prompt) self._previous_widget = PreviousWidget.none self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() prompter = objreg.get('prompter', scope='window', window=self._win_id) prompter.show_prompt.connect(self._show_prompt_widget) prompter.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) def __repr__(self): return utils.get_repr(self) @pyqtProperty(bool) def error(self): """Getter for self.error, so it can be used as Qt property.""" # pylint: disable=method-hidden return self._error def _set_error(self, val): """Setter for self.error, so it can be used as Qt property. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if self._error == val: # This gets called a lot (e.g. if the completion selection was # changed), and setStyleSheet is relatively expensive, so we ignore # this if there's nothing to change. return log.statusbar.debug("Setting error to {}".format(val)) self._error = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) if val: # If we got an error while command/prompt was shown, raise the text # widget. self._stack.setCurrentWidget(self.txt) @pyqtProperty(bool) def prompt_active(self): """Getter for self.prompt_active, so it can be used as Qt property.""" # pylint: disable=method-hidden return self._prompt_active def _set_prompt_active(self, val): """Setter for self.prompt_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ log.statusbar.debug("Setting prompt_active to {}".format(val)) self._prompt_active = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) @pyqtProperty(bool) def insert_active(self): """Getter for self.insert_active, so it can be used as Qt property.""" # pylint: disable=method-hidden return self._insert_active def _set_insert_active(self, val): """Setter for self.insert_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ log.statusbar.debug("Setting insert_active to {}".format(val)) self._insert_active = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _pop_text(self): """Display a text in the statusbar and pop it from _text_queue.""" try: error, text = self._text_queue.popleft() except IndexError: self._set_error(False) self.txt.set_text(self.txt.Text.temp, '') self._text_pop_timer.stop() # If a previous widget was interrupted by an error, restore it. if self._previous_widget == PreviousWidget.prompt: self._stack.setCurrentWidget(self.prompt) elif self._previous_widget == PreviousWidget.command: self._stack.setCurrentWidget(self.command) elif self._previous_widget == PreviousWidget.none: pass else: raise AssertionError("Unknown _previous_widget!") return log.statusbar.debug("Displaying {} message: {}".format( 'error' if error else 'text', text)) log.statusbar.debug("Remaining: {}".format(self._text_queue)) self._set_error(error) self.txt.set_text(self.txt.Text.temp, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._set_error(False) self._previous_widget = PreviousWidget.prompt if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.cmd) def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget, queue: {}".format( self._text_queue)) self._previous_widget = PreviousWidget.none if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) def _show_prompt_widget(self): """Show prompt widget instead of temporary text.""" if self._stack.currentWidget() is self.prompt: return self._set_error(False) self._set_prompt_active(True) self._previous_widget = PreviousWidget.prompt if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.prompt) def _hide_prompt_widget(self): """Show temporary text instead of prompt widget.""" self._set_prompt_active(False) self._previous_widget = PreviousWidget.none log.statusbar.debug("Hiding prompt widget, queue: {}".format( self._text_queue)) if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) def _disp_text(self, text, error, immediately=False): """Inner logic for disp_error and disp_temp_text. Args: text: The message to display. error: Whether it's an error message (True) or normal text (False) immediately: If set, message gets displayed immediately instead of queued. """ log.statusbar.debug("Displaying text: {} (error={})".format( text, error)) mindelta = config.get('ui', 'message-timeout') if self._stopwatch.isNull(): delta = None self._stopwatch.start() else: delta = self._stopwatch.restart() log.statusbar.debug("queue: {} / delta: {}".format( self._text_queue, delta)) if not self._text_queue and (delta is None or delta > mindelta): # If the queue is empty and we didn't print messages for long # enough, we can take the short route and display the message # immediately. We then start the pop_timer only to restore the # normal state in 2 seconds. log.statusbar.debug("Displaying immediately") self._set_error(error) self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() elif self._text_queue and self._text_queue[-1] == (error, text): # If we get the same message multiple times in a row and we're # still displaying it *anyways* we ignore the new one log.statusbar.debug("ignoring") elif immediately: # This message is a reaction to a keypress and should be displayed # immediately, temporarily interrupting the message queue. # We display this immediately and restart the timer.to clear it and # display the rest of the queue later. log.statusbar.debug("Moving to beginning of queue") self._set_error(error) self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() else: # There are still some messages to be displayed, so we queue this # up. log.statusbar.debug("queueing") self._text_queue.append((error, text)) self._text_pop_timer.start() @pyqtSlot(str, bool) def disp_error(self, text, immediately=False): """Display an error in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, True, immediately) @pyqtSlot(str, bool) def disp_temp_text(self, text, immediately): """Display a temporary text in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, False, immediately) @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) if mode in mode_manager.passthrough: text = "-- {} MODE --".format(mode.name.upper()) self.txt.set_text(self.txt.Text.normal, text) if mode == usertypes.KeyMode.insert: self._set_insert_active(True) @pyqtSlot(usertypes.KeyMode) def on_mode_left(self, mode): """Clear marked mode.""" mode_manager = objreg.get('mode-manager', scope='window', window=self._win_id) if mode in mode_manager.passthrough: self.txt.set_text(self.txt.Text.normal, '') if mode == usertypes.KeyMode.insert: self._set_insert_active(False) @config.change_filter('ui', 'message-timeout') def set_pop_timer_interval(self): """Update message timeout when config changed.""" self._text_pop_timer.setInterval(config.get('ui', 'message-timeout')) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos())
def artisticSleep(sleepTime): time = QTime() time.restart() while time.elapsed() < sleepTime: QApplication.processEvents(QEventLoop.AllEvents, 50)
class Example(QMainWindow): def __init__(self, pipe): super().__init__() self.pipe = pipe self.gameConfig = GameConfig() self.playing = False self.game_over = [] self.all_die = 0 self.currentPlayer = 0 self.timer = QBasicTimer( ) # Used for controlling the game speed, and the canvas update self.speed = 100 self.timeCounter = 0 self.playtime = QTime() self.counter = [] self.rectangles_to_draw = [] self.playerLabels = [] self.scoreLabels = [] self.sec_counter = 1 self.special_food_border = False self.special_food = False self.score = [0, 0, 0, 0] self.initUI() # definise izgled glavnog prozora def initUI(self): self.setGeometry(200, 200, 900, 600) self.setWindowTitle("TurnSnakeGdxGame") self.setWindowIcon(QIcon('snake.png')) self.setStyleSheet("background-image : url(rsz_snake_background.png);") self.timerLabel = QLabel(self) self.timeElapsed = "Time Elapsed:" self.timerLabel.setText(str(self.timeElapsed)) self.timerLabel.resize(100, 50) self.timerLabel.move(600, 450) self.timerLabel.setStyleSheet("color: black;") self.timerCounterLabel = QLabel(self) self.timeCounter = 0 self.timerCounterLabel.setText(str(self.timeCounter)) self.timerCounterLabel.resize(50, 50) self.timerCounterLabel.move(700, 450) self.timerCounterLabel.setStyleSheet("color: black;") # next player button self.btn = QPushButton('Next Player', self) self.btn.setStyleSheet("background-color: purple; color: white;") self.btn.clicked.connect(self.next_player) self.btn.setGeometry(600, 520, 270, 50) menu = self.menuBar().addMenu("New game") self.menuBar().setStyleSheet("color: black;") self.hostAct = QAction("&Start Game", self) self.hostAct.triggered.connect(self.start) menu.addAction(self.hostAct) self.show() # metoda koja poziva metode za crtanje svih elemenata na terenu def paintEvent(self, e): qp = QPainter() qp.begin(self) self.draw_rectangles(qp) if self.playing is True: if self.special_food_border is False: if self.sec_counter % 17 == 0: self.draw_border() self.special_food_border = True qp.end() painter = QPainter(self) painter.setPen(QPen(Qt.darkGreen, 20, Qt.SolidLine)) painter.drawRect(20, 40, 520, 540) # iscrtava hranu i zmije def draw_rectangles(self, qp): col = QColor(0, 0, 0) col.setNamedColor('#d4d4d4') qp.setPen(col) for rect in self.rectangles_to_draw: qp.setBrush(rect['color']) qp.drawRect(rect['x'], rect['y'], rect['width'], rect['height']) ## crta granicu terena def draw_border(self): painter = QPainter(self) painter.setPen(QPen(Qt.darkGreen, 5, Qt.SolidLine)) painter.drawRect(450, 500, 60, 60) ## postavljanje labela za rezultat igraca def set_labels(self): for i in range(self.gameConfig.playerNumber): space = 15 + i * 50 self.playerLabels.append(QLabel(self)) self.player = "Player {}:".format(i + 1) self.playerLabels[i].setText(str(self.player)) self.playerLabels[i].setGeometry(600, space, 100, 50) self.playerLabels[i].setStyleSheet("color: black;") self.playerLabels[i].show() self.scoreLabels.append(QLabel(self)) self.score[i] = 0 self.scoreLabels[i].setText(str(self.score[3])) self.scoreLabels[i].setGeometry(660, space, 200, 50) self.scoreLabels[i].setStyleSheet("color: black;") self.scoreLabels[i].show() # sakrivanje labela ukoliko je broj igraca manji od 4 def hide_labels(self): for i in range(self.gameConfig.playerNumber): self.playerLabels[i].hide() self.scoreLabels[i].hide() # promena boje teksta u labelama kao indikator aktivnosti trenutnog igraca def change_label_color(self): for i in range(self.gameConfig.playerNumber): self.playerLabels[i].setStyleSheet("color: black;") if self.currentPlayer == 0: self.playerLabels[0].setStyleSheet("color: red;") elif self.currentPlayer == 1: self.playerLabels[1].setStyleSheet("color: green;") elif self.currentPlayer == 2: self.playerLabels[2].setStyleSheet("color: blue;") elif self.currentPlayer == 3: self.playerLabels[3].setStyleSheet("color: purple;") # signalizira izmenu igraca def next_player(self): if self.playing is True: self.pipe.send({ 'event_type': 'next_player', 'data': 'next_player' }) time.sleep(0.1) # registruje da je tipka pritisnuta i salje informaciju u pajp def keyPressEvent(self, e): if self.playing is True: self.pipe.send({'event_type': 'key_pressed', 'data': e.key()}) time.sleep(0.2) # thread def listen(self): while True: try: receive = self.pipe.recv() if receive['event_type'] == 'rectangles': self.rectangles_to_draw = receive['data'] self.update() elif receive['event_type'] == 'score': self.update_score(receive['data'], 1) elif receive['event_type'] == 'special_score': self.update_score(receive['data'], receive['score_type']) self.update_spec_food_value() elif receive['event_type'] == 'end_game': self.all_die += 1 self.set_game_over(receive['data']) elif receive['event_type'] == 'current_player': self.gameConfig.turnPlanTime = self.timeCounter self.timerCounterLabel.setText(str(self.timeCounter)) self.currentPlayer = receive['data'] self.change_label_color() except BrokenPipeError as e: print(e) print('Broken pipe error') break except EOFError as e: print(e) print('EOFError') break # resetuje brojac za specijalnu hranu def update_spec_food_value(self): self.special_food = False self.special_food_border = False self.sec_counter = 1 # slanje podataka u pajp i startovanje treda koji konstantno osluskuje da li ima pristiglih podataka def do_action(self, config: GameConfig): self.pipe.send({'event_type': 'start_game', 'data': config}) # start thread which listens on the child_connection t = Thread(target=self.listen) t.start() def start(self): dialog = StartDialog(self) dialog.exec() # pokrece tajmer def reset_value(self): for i in range(self.gameConfig.playerNumber): self.game_over.append(1) for i in range(self.gameConfig.playerNumber): self.counter.append(0) self.playing = True self.timeCounter = self.gameConfig.turnPlanTime self.speed = 100 self.playtime.start() self.timer.start(self.speed, Qt.PreciseTimer, self) # definise akciju posle pritisnutog start game dugmeta def start_game_pressed(self, gameConfig: GameConfig): self.menuBar().setDisabled(True) self.gameConfig = gameConfig if self.gameConfig.playerNumber > 4 or self.gameConfig.playerNumber < 2: dialog = ErrorDialog(self) dialog.exec() self.start() else: self.reset_value() self.set_labels() self.change_label_color() self.do_action(self.gameConfig) # prikazuje dijalog na ekranu def show_dialog(self, player: int): end_dialog = EndGameDialog(self, player) end_dialog.exec() # prikazuje specijalnu hranu def show_special_food(self): self.pipe.send({'event_type': 'special_food', 'data': 'next_player'}) time.sleep(0.1) self.special_food = True def timerEvent(self, event: QTimerEvent) -> None: """ In charge of, in this case, update the game and check the conditions to continue playing, grow, spawn food and special item """ if self.playtime.elapsed() > 1000: self.sec_counter += 1 self.gameConfig.turnPlanTime -= 1.0 self.timerCounterLabel.setText(str(self.gameConfig.turnPlanTime)) self.playtime.restart() if self.gameConfig.turnPlanTime == 0: self.next_player() self.gameConfig.turnPlanTime = self.timeCounter self.timerCounterLabel.setText(str(self.timeCounter)) if self.sec_counter % 17 == 0: self.update() if self.sec_counter % 19 == 0 and self.special_food is False: self.show_special_food() # Check if the event if from the self.timer if event.timerId() is self.timer.timerId(): if self.playing is True: if self.all_die == self.gameConfig.playerNumber - 1: winner = self.winner() self.playing = False self.show_dialog(winner) self.timer.stop() return else: super(Example, self).timerEvent(event) # odredjuje koji igrac je pobedio def winner(self): for i in range(len(self.game_over)): if self.game_over[i] == 1: return i + 1 # salje signal da je igra gotova u pajp def end_game(self, winner: int): self.pipe.send({'event_type': 'delete_all', 'data': winner}) self.hide_labels() # salje signal da je za odredjenog igraca igra gotova def set_game_over(self, player: int): for i in range(self.gameConfig.playerNumber): if player == i: self.score[i] = "Game over" self.scoreLabels[i].setText(str(self.score[i])) self.game_over[i] = 0 # menja rezultat u labelama za rezultat def update_score(self, player: int, points: int): for i in range(self.gameConfig.playerNumber): if player == i: self.score[i] = self.score[i] + points self.scoreLabels[i].setText(str(self.score[i])) def closeEvent(self, event): self.pipe.send({'event_type': 'close_app'})
class Connection(QTcpSocket): """ Class representing a peer connection. @signal readyForUse() emitted when the connection is ready for use @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal getParticipants() emitted after a get participants message has arrived @signal participants(participants) emitted after the list of participants has arrived (list of strings of "host:port") """ WaitingForGreeting = 0 ReadingGreeting = 1 ReadyForUse = 2 PlainText = 0 Ping = 1 Pong = 2 Greeting = 3 GetParticipants = 4 Participants = 5 Editor = 6 Undefined = 99 ProtocolMessage = "MESSAGE" ProtocolPing = "PING" ProtocolPong = "PONG" ProtocolGreeting = "GREETING" ProtocolGetParticipants = "GET_PARTICIPANTS" ProtocolParticipants = "PARTICIPANTS" ProtocolEditor = "EDITOR" readyForUse = pyqtSignal() newMessage = pyqtSignal(str, str) getParticipants = pyqtSignal() participants = pyqtSignal(list) editorCommand = pyqtSignal(str, str, str) rejected = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent referenec to the parent object (QObject) """ super(Connection, self).__init__(parent) self.__greetingMessage = self.tr("undefined") self.__username = self.tr("unknown") self.__serverPort = 0 self.__state = Connection.WaitingForGreeting self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = -1 self.__transferTimerId = 0 self.__isGreetingMessageSent = False self.__pingTimer = QTimer(self) self.__pingTimer.setInterval(PingInterval) self.__pongTime = QTime() self.__buffer = QByteArray() self.__client = None self.readyRead.connect(self.__processReadyRead) self.disconnected.connect(self.__disconnected) self.__pingTimer.timeout.connect(self.__sendPing) self.connected.connect(self.__sendGreetingMessage) def name(self): """ Public method to get the connection name. @return connection name (string) """ return self.__username def serverPort(self): """ Public method to get the server port. @return server port (integer) """ return self.__serverPort def setClient(self, client): """ Public method to set the reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__client = client def setGreetingMessage(self, message, serverPort): """ Public method to set the greeting message. @param message greeting message (string) @param serverPort port number to include in the message (integer) """ self.__greetingMessage = "{0}:{1}".format(message, serverPort) def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) @return flag indicating a successful send (boolean) """ if message == "": return False msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolMessage, SeparatorToken, msg.size()) .encode("utf-8")) + msg return self.write(data) == data.size() def timerEvent(self, evt): """ Protected method to handle timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__transferTimerId: self.abort() self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 def __processReadyRead(self): """ Private slot to handle the readyRead signal. """ if self.__state == Connection.WaitingForGreeting: if not self.__readProtocolHeader(): return if self.__currentDataType != Connection.Greeting: self.abort() return self.__state = Connection.ReadingGreeting if self.__state == Connection.ReadingGreeting: if not self.__hasEnoughData(): return self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return try: user, serverPort = \ str(self.__buffer, encoding="utf-8").split(":") except ValueError: self.abort() return self.__serverPort = int(serverPort) hostInfo = QHostInfo.fromName(self.peerAddress().toString()) self.__username = "******".format( user, hostInfo.hostName(), self.peerPort() ) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() if not self.isValid(): self.abort() return bannedName = "{0}@{1}".format( user, hostInfo.hostName(), ) Preferences.syncPreferences() if bannedName in Preferences.getCooperation("BannedUsers"): self.rejected.emit(self.tr( "* Connection attempted by banned user '{0}'.") .format(bannedName)) self.abort() return if self.__serverPort != self.peerPort() and \ not Preferences.getCooperation("AutoAcceptConnections"): # don't ask for reverse connections or # if we shall accept automatically res = E5MessageBox.yesNo( None, self.tr("New Connection"), self.tr("""<p>Accept connection from """ """<strong>{0}@{1}</strong>?</p>""").format( user, hostInfo.hostName()), yesDefault=True) if not res: self.abort() return if self.__client is not None: chatWidget = self.__client.chatWidget() if chatWidget is not None and not chatWidget.isVisible(): e5App().getObject( "UserInterface").activateCooperationViewer() if not self.__isGreetingMessageSent: self.__sendGreetingMessage() self.__pingTimer.start() self.__pongTime.start() self.__state = Connection.ReadyForUse self.readyForUse.emit() while self.bytesAvailable(): if self.__currentDataType == Connection.Undefined: if not self.__readProtocolHeader(): return if not self.__hasEnoughData(): return self.__processData() def __sendPing(self): """ Private slot to send a ping message. """ if self.__pongTime.elapsed() > PongTimeout: self.abort() return self.write("{0}{1}1{1}p".format( Connection.ProtocolPing, SeparatorToken)) def __sendGreetingMessage(self): """ Private slot to send a greeting message. """ greeting = QByteArray(self.__greetingMessage.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolGreeting, SeparatorToken, greeting.size()) .encode("utf-8")) + greeting if self.write(data) == data.size(): self.__isGreetingMessageSent = True def __readDataIntoBuffer(self, maxSize=MaxBufferSize): """ Private method to read some data into the buffer. @param maxSize maximum size of data to read (integer) @return size of data read (integer) """ if maxSize > MaxBufferSize: return 0 numBytesBeforeRead = self.__buffer.size() if numBytesBeforeRead == MaxBufferSize: self.abort() return 0 while self.bytesAvailable() and self.__buffer.size() < maxSize: self.__buffer.append(self.read(1)) if self.__buffer.endsWith(SeparatorToken): break return self.__buffer.size() - numBytesBeforeRead def __dataLengthForCurrentDataType(self): """ Private method to get the data length for the current data type. @return data length (integer) """ if self.bytesAvailable() <= 0 or \ self.__readDataIntoBuffer() <= 0 or \ not self.__buffer.endsWith(SeparatorToken): return 0 self.__buffer.chop(len(SeparatorToken)) number = self.__buffer.toInt()[0] self.__buffer.clear() return number def __readProtocolHeader(self): """ Private method to read the protocol header. @return flag indicating a successful read (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__readDataIntoBuffer() <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False self.__buffer.chop(len(SeparatorToken)) if self.__buffer == Connection.ProtocolPing: self.__currentDataType = Connection.Ping elif self.__buffer == Connection.ProtocolPong: self.__currentDataType = Connection.Pong elif self.__buffer == Connection.ProtocolMessage: self.__currentDataType = Connection.PlainText elif self.__buffer == Connection.ProtocolGreeting: self.__currentDataType = Connection.Greeting elif self.__buffer == Connection.ProtocolGetParticipants: self.__currentDataType = Connection.GetParticipants elif self.__buffer == Connection.ProtocolParticipants: self.__currentDataType = Connection.Participants elif self.__buffer == Connection.ProtocolEditor: self.__currentDataType = Connection.Editor else: self.__currentDataType = Connection.Undefined self.abort() return False self.__buffer.clear() self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() return True def __hasEnoughData(self): """ Private method to check, if enough data is available. @return flag indicating availability of enough data (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__numBytesForCurrentDataType <= 0: self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() if self.bytesAvailable() < self.__numBytesForCurrentDataType or \ self.__numBytesForCurrentDataType <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False return True def __processData(self): """ Private method to process the received data. """ self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return if self.__currentDataType == Connection.PlainText: self.newMessage.emit( self.__username, str(self.__buffer, encoding="utf-8")) elif self.__currentDataType == Connection.Ping: self.write("{0}{1}1{1}p".format( Connection.ProtocolPong, SeparatorToken)) elif self.__currentDataType == Connection.Pong: self.__pongTime.restart() elif self.__currentDataType == Connection.GetParticipants: self.getParticipants.emit() elif self.__currentDataType == Connection.Participants: msg = str(self.__buffer, encoding="utf-8") if msg == "<empty>": participantsList = [] else: participantsList = msg.split(SeparatorToken) self.participants.emit(participantsList[:]) elif self.__currentDataType == Connection.Editor: hash, fn, msg = \ str(self.__buffer, encoding="utf-8").split(SeparatorToken) self.editorCommand.emit(hash, fn, msg) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() def sendGetParticipants(self): """ Public method to request a list of participants. """ self.write( "{0}{1}1{1}l".format( Connection.ProtocolGetParticipants, SeparatorToken) ) def sendParticipants(self, participants): """ Public method to send the list of participants. @param participants list of participants (list of strings of "host:port") """ if participants: message = SeparatorToken.join(participants) else: message = "<empty>" msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolParticipants, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ msg = QByteArray("{0}{1}{2}{1}{3}".format( projectHash, SeparatorToken, filename, message).encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolEditor, SeparatorToken, msg.size()) .encode("utf-8")) + msg self.write(data) def __disconnected(self): """ Private slot to handle the connection being dropped. """ self.__pingTimer.stop() if self.__state == Connection.WaitingForGreeting: self.rejected.emit(self.tr( "* Connection to {0}:{1} refused.").format( self.peerName(), self.peerPort()))
class PrettyWidget(QOpenGLWidget): started = False finished = False timer = None port_trigger = None current_index = None presenting = None paused = False delay = 0 # used when pausing cross_delay = 2 cross_color = 'green' sound = {'start': None, 'end': None} fast_tsv = None fast_i = None fast_t = None def __init__(self, parameters): super().__init__() self.P = parameters if self.P['SOUND']['PLAY']: self.sound = { 'start': QSound(str(SOUNDS_DIR / self.P['SOUND']['START'])), 'end': QSound(str(SOUNDS_DIR / self.P['SOUND']['END'])), } self.open_serial() try: port_input = Serial(self.P['COM']['INPUT']['PORT'], baudrate=self.P['COM']['INPUT']['BAUDRATE']) except SerialException: port_input = None lg.warning('could not open serial port to read input') _warn_about_ports() self.port_input = port_input self.start_serial_input() lg.info('Reading images') self.stimuli = read_stimuli(self.P) lg.info('Reading images: finished') # background color self.bg_color = QColor(self.P['BACKGROUND']) self.show() self.time = QTime() self.timer = QTimer() self.timer.setTimerType(Qt.PreciseTimer) self.timer.timeout.connect(self.check_time) self.setCursor(Qt.BlankCursor) self.setGeometry(200, 200, 1000, 1000) if self.P['FULLSCREEN']: self.showFullScreen() else: self.showNormal() self.serial(250) if self.P['DATAGLOVE']: self.open_dataglove() def open_dataglove(self): lg.info('Opening dataglove') self.glove = [] if FiveDTGlove.gloveDLL is None: # could not initialize DLL return for i in range(2): # TODO: we should use scan_USB but I get error logname = self.P['logname'] DATAGLOVE_LOG = logname.parent / (logname.stem + f'_dataglove{i}.txt') new_glove = FiveDTGlove(DATAGLOVE_LOG) try: new_glove.open(f'USB{i}'.encode()) except IOError: pass else: self.glove.append(new_glove) def open_serial(self): try: self.port_trigger = Serial( self.P['COM']['TRIGGER']['PORT'], baudrate=self.P['COM']['TRIGGER']['BAUDRATE']) except SerialException: lg.warning('could not open serial port for triggers') _warn_about_ports() def serial(self, trigger): """trigger needs to be between 0 and 255. If none, then it closes the serial port""" if trigger is None: if self.port_trigger is not None: self.port_trigger.close() else: lg.debug(f'Sending trigger {trigger:03d}') if self.port_trigger is not None: try: self.port_trigger.write(pack('>B', trigger)) except Exception: lg.warning('could not write to serial port') self.open_serial() def paintGL(self): window_rect = self.rect() rect_x = window_rect.center().x() + self.P['SCREEN']['RIGHTWARDS'] rect_y = window_rect.center().y() + self.P['SCREEN']['DOWNWARDS'] qp = QPainter() qp.begin(self) qp.fillRect(window_rect, self.bg_color) if self.paused: self.draw_text(qp, 'PAUSED') elif self.current_index is None: self.draw_text(qp, 'READY') else: if self.fast_tsv is not None: i_pixmap = where(self.fast_tsv['onset'] <= self.fast_i)[0][-1] if self.fast_i == self.fast_tsv['onset'][-1]: self.fast_tsv = None self.fast_i = None self.frameSwapped.disconnect() else: if self.fast_tsv['stim_file'][i_pixmap] is not None: current_pixmap = self.fast_tsv['stim_file'][i_pixmap] image_rect = current_pixmap.rect() size = image_rect.size().scaled( window_rect.size(), Qt.KeepAspectRatio) img_origin_x = rect_x - int(size.width() / 2) img_origin_y = rect_y - int(size.height() / 2) qp.beginNativePainting() qp.drawPixmap(img_origin_x, img_origin_y, size.width(), size.height(), current_pixmap) qp.endNativePainting() lg.debug(f'FAST IMAGE #{self.fast_i}') self.fast_i += 1 else: current_pixmap = self.stimuli['stim_file'][self.current_index] if isinstance(current_pixmap, Path): self.fast_tsv = read_fast_stimuli(current_pixmap) self.fast_i = 0 elif isinstance(current_pixmap, str): self.draw_text(qp, current_pixmap) if current_pixmap == 'END': if not self.finished: self.draw_text(qp, 'END') self.finished = True self.serial(None) if self.sound['end'] is not None: self.sound['end'].play() else: image_rect = current_pixmap.rect() size = image_rect.size().scaled(window_rect.size(), Qt.KeepAspectRatio) img_origin_x = rect_x - int(size.width() / 2) img_origin_y = rect_y - int(size.height() / 2) qp.drawPixmap(img_origin_x, img_origin_y, size.width(), size.height(), current_pixmap) self.drawText(qp) qp.end() if self.presenting is not None: # send triggers and log info right after the image was presented trial = self.stimuli[self.presenting] lg.info('Presenting ' + str(trial['trial_name'])) self.serial(trial['trial_type']) self.presenting = None if self.fast_i == 0: self.input_thread.msleep(1000) self.frameSwapped.connect(self.update) self.update() def drawText(self, qp): if not self.P['FIXATION']['ACTIVE']: return elapsed = self.time.elapsed() + self.delay if elapsed > self.cross_delay: if self.cross_color == 'green': self.cross_color = 'red' self.serial(240) else: self.cross_color = 'green' self.serial(241) self.cross_delay += random() * 5000 + 2000 color = QColor(self.cross_color) qp.setPen(color) qp.setFont(QFont('SansSerif', 50)) qp.drawText(*self.center_rect(), Qt.AlignCenter, '+') def draw_text(self, qp, text): qp.setPen(QColor(40, 40, 255)) qp.setFont(QFont('Decorative', 50)) qp.drawText(*self.center_rect(), Qt.AlignCenter, text) def center_rect(self): window_rect = self.rect() width = window_rect.width() height = window_rect.height() img_origin_x = window_rect.center().x() - int( width / 2) + self.P['SCREEN']['RIGHTWARDS'] img_origin_y = window_rect.center().y() - int( height / 2) + self.P['SCREEN']['DOWNWARDS'] return (img_origin_x, img_origin_y, width, height) def check_time(self): elapsed = self.time.elapsed() + self.delay if self.P['DATAGLOVE']: for glove in self.glove: if glove.new_data: glove_data = glove.get_sensor_raw_all() glove.f.write(datetime.now().strftime('%H:%M:%S.%f') + '\t' + '\t'.join([f'{x}' for x in glove_data]) + '\n') index_image = where((self.stimuli['onset'] * 1e3) <= elapsed)[0] if len(index_image) == len(self.stimuli): self.stop() elif len(index_image) > 0: index_image = index_image[-1] if index_image != self.current_index: self.current_index = index_image if index_image is not None: self.presenting = index_image self.update() def start(self): if self.started: return lg.warning('Starting') self.started = True self.current_index = -1 self.time.start() self.timer.start(self.P['QTIMER_INTERVAL']) if self.sound['start'] is not None: self.sound['start'].play() def start_serial_input(self): self.input_worker = SerialInputWorker() self.input_worker.port_input = self.port_input self.input_thread = QThread(parent=self) self.input_thread.started.connect(self.input_worker.start_reading) self.input_worker.signal_to_main.connect(self.read_serial_input) self.input_worker.moveToThread(self.input_thread) self.input_thread.start() self.input_thread.setPriority(QThread.LowestPriority) def read_serial_input(self, number): lg.info(f'Received input trigger {number}') if self.P['COM']['INPUT']['START_TRIGGER'] == number: self.start() self.serial(254) def stop(self): lg.info('Stopping task') if self.timer is not None: self.timer.stop() # nice wayt to stop the worker self.input_worker.running = False self.input_thread.terminate() sleep(1) app.exit(0) def pause(self): if not self.paused: self.paused = True self.delay += self.time.elapsed() self.timer.stop() self.serial(253) lg.info('Pausing the task') else: self.paused = False self.time.restart() self.serial(254) lg.info('Pause finished: restarting the task') self.timer.start(self.P['QTIMER_INTERVAL']) self.update() def keyPressEvent(self, event): if isinstance(event, QKeyEvent): if event.key() in (Qt.Key_Enter, Qt.Key_Return): self.start() elif event.key() == Qt.Key_Space: self.pause() elif event.key() == Qt.Key_Escape: lg.info('Pressed Escape') self.serial(255) self.stop() elif event.key() == Qt.Key_PageUp: self.showFullScreen() elif event.key() == Qt.Key_PageDown: self.showNormal() else: super().keyPressEvent(event) else: super().keyPressEvent(event) def mouseDoubleClickEvent(self, event): if isinstance(event, QMouseEvent): if event.pos().x() > self.rect().center().x(): if not self.started: self.start() else: self.pause() else: if self.isFullScreen(): self.showNormal() else: self.showFullScreen() else: super().mouseDoubleClickEvent(event) def closeEvent(self, event): self.stop() event.accept()
class Example(QWidget): def __init__(self, vehicles_N, vehicles_W, vehicles_E): super().__init__() self.vehicles_N = vehicles_N self.vehicles_W = vehicles_W self.vehicles_E = vehicles_E self.initUI() self.timer = QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000 / 60) #一秒間隔で更新 self.t = QTime() self.t.start() self.show() def initUI(self): self.setGeometry(300, 300, 600, 600) self.setWindowTitle("Koku's Simulation") self.ti = 0 self.beze_t = [] self.r = [] self.up_left_x = [] self.up_left_y = [] self.down_left_x = [] self.down_left_y = [] self.up_right_x = [] self.up_right_y = [] self.down_right_x = [] self.down_right_y = [] for i in range(10): self.beze_t.append(0) self.r.append(0) self.up_left_x.append(0) self.up_left_y.append(0) self.down_left_x.append(0) self.down_left_y.append(0) self.up_right_x.append(0) self.up_right_y.append(0) self.down_right_x.append(0) self.down_right_y.append(0) self.single_0_0 = True self.single_0_1 = True self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] self.grid = {} for i in range(270, 330, 10): for j in range(270, 330, 10): self.grid[(i, j)] = True def paintEvent(self, e): #print("!") qp = QPainter(self) self.drawLines(qp) self.drawSignals_0(qp) self.drawVehicles(qp) def drawLines(self, qp): # print(self.t.elapsed()) pen = QPen(Qt.black, 2, Qt.SolidLine) pen_dash = QPen(Qt.black, 2, Qt.DotLine) # Vertical qp.setPen(pen) qp.drawLine(270, 0, 270, 600) # with grids ################## # qp.drawLine(280, 0, 280, 600) # qp.drawLine(290, 0, 290, 600) # qp.drawLine(300, 0, 300, 600) # qp.drawLine(310, 0, 310, 600) # qp.drawLine(320, 0, 320, 600) # with grids ################## qp.drawLine(330, 0, 330, 600) qp.drawLine(300, 0, 300, 270) qp.drawLine(300, 330, 300, 600) qp.setPen(pen_dash) qp.drawLine(280, 330, 280, 600) qp.drawLine(290, 330, 290, 600) qp.drawLine(310, 330, 310, 600) qp.drawLine(320, 330, 320, 600) qp.drawLine(280, 0, 280, 270) qp.drawLine(290, 0, 290, 270) qp.drawLine(310, 0, 310, 270) qp.drawLine(320, 0, 320, 270) # Tropical qp.setPen(pen) qp.drawLine(0, 270, 600, 270) # with grids ################## # qp.drawLine(0, 280, 600, 280) # qp.drawLine(0, 290, 600, 290) # qp.drawLine(0, 300, 600, 300) # qp.drawLine(0, 310, 600, 310) # qp.drawLine(0, 320, 600, 320) # with grids ################## qp.drawLine(0, 330, 600, 330) qp.drawLine(0, 300, 270, 300) qp.drawLine(330, 300, 600, 300) qp.setPen(pen_dash) qp.drawLine(0, 280, 270, 280) qp.drawLine(0, 290, 270, 290) qp.drawLine(0, 310, 270, 310) qp.drawLine(0, 320, 270, 320) qp.drawLine(330, 280, 600, 280) qp.drawLine(330, 290, 600, 290) qp.drawLine(330, 310, 600, 310) qp.drawLine(330, 320, 600, 320) def drawSignals_0(self, qp): #print(self.t.elapsed()) if 1000 < self.t.elapsed() < 2000: qp.setPen(Qt.black) qp.setBrush(Qt.red) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = False self.single_0_1 = True else: qp.setPen(Qt.black) qp.setBrush(Qt.green) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = True self.single_0_1 = False def coordinate_up_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_up_left_y(self, po_y): return po_y def coordinate_up_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_up_right_y(self, po_y): return po_y def coordinate_down_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_down_left_y(self, po_y, r): return po_y + 5 * math.sin(math.radians(r)) + 10 * math.cos( math.radians(r)) def coordinate_down_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_down_right_y(self, po_y, r): return po_y + 10 * math.sin(math.radians(r)) + 5 * math.cos( math.radians(r)) def drawVehicles(self, qp): qp.setPen(Qt.black) qp.setBrush(Qt.green) # # Vehicles from North for i, veh in enumerate(vehicles_N): if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_N: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) else: if veh.getPosition().y + veh.getSpeed( ).y > 260 and veh.getPosition().y <= 260: if self.single_0_1: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) else: if veh.getPosition().y <= 270: if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: veh.getPosition().y += veh.getSpeed().y qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) self.grid[( veh.getPosition().x // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False self.grid[( (veh.getPosition().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False else: try: if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: self.vehicles_N[i].getPosition( ).y += veh.getSpeed().y self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False self.grid[( (veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False self.grid[( (veh.getPosition().x + veh.getSpeed().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False self.grid[( (veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False if self.vehicles_N[i].getPosition( ).y > 600: self.vehicles_N[i].getPosition().y = 0 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) except KeyError: self.vehicles_N[i].getPosition( ).y += veh.getSpeed().y if self.vehicles_N[i].getPosition().y > 600: self.vehicles_N[i].getPosition().y = 0 qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) else: # print(self.single_0_1) veh.getPosition().y += veh.getSpeed().y if veh.getPosition().y > 600: veh.getPosition().y = 0 # print(self.t.elapsed()) qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) for i in range(11): self.collision_check_N.append( (veh.getPosition().x, veh.getPosition().y - i)) #print(self.collision_check) # Vehicles from West for i, veh in enumerate(vehicles_W): # Check if there are vehicles ahead. If true, stop if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_W: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # Make the room not available for other vehicles for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Move forward else: # Just before the intersection if veh.getPosition().x + 10 + 2 > 270 and veh.getPosition( ).x <= 270 - 10: # Check traffic signal. True, then stop before entering. if self.single_0_0: qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Enter intersection else: veh.getPosition().x += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Light up the grids in the intersection # Up left if (veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: self.grid[(veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10)] = False #print('success, x:', veh.getPosition().x) # Up right if ((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: self.grid[((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10)] = False #print('success, x:', veh.getPosition().x) # Down left if (veh.getPosition().x // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: self.grid[(veh.getPosition().x // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False #print('success, x:', veh.getPosition().x) # Down right if ((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: self.grid[((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False #print('success, x:', veh.getPosition().x) # Already in the intersection else: if 270 < veh.getPosition().x < 328 and veh.getPosition( ).y < 330: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) # Calculate rotation angle if (((veh.getPosition().x - 270 + 3) / 60) * 90 > 15): self.r[i] = ( (veh.getPosition().x - 270 + 3) / 60) * 90 qp.rotate(self.r[i]) else: self.r[i] = 0 qp.rotate(self.r[i]) qp.translate(-veh.getPosition().x, -veh.getPosition().y) # Calculate trajectory by using Bezier Curve x = pow(1 - (self.beze_t[i] / 60), 2) * 272 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 330 + pow( self.beze_t[i] / 60, 2) * 330 y = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 273 + pow( self.beze_t[i] / 60, 2) * 330 veh.setPosition(Position(x, y)) self.beze_t[i] += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) qp.restore() # Calculate the big Square's coordinate self.up_left_x[i] = self.coordinate_up_left_x( veh.getPosition().x, self.r[i]) self.up_left_y[i] = self.coordinate_up_left_y( veh.getPosition().y) self.down_left_x[i] = self.coordinate_down_left_x( veh.getPosition().x, self.r[i]) self.down_left_y[i] = self.coordinate_down_left_y( veh.getPosition().y, self.r[i]) self.up_right_x[i] = self.coordinate_up_right_x( veh.getPosition().x, self.r[i]) self.up_right_y[i] = self.coordinate_up_right_y( veh.getPosition().y) self.down_right_x[i] = self.coordinate_down_right_x( veh.getPosition().x, self.r[i]) self.down_right_y[i] = self.coordinate_down_right_y( veh.getPosition().y, self.r[i]) # Up left if (self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10) in self.grid: self.grid[(self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10)] = False # print('success') # Up right if ((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10) in self.grid: self.grid[((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10)] = False # print('success') # Down left if (self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10) in self.grid: self.grid[(self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10)] = False # print('success') # Down right if ((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10) in self.grid: self.grid[((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10)] = False # print('success') # Already left intersection elif 328 <= veh.getPosition().x and veh.getPosition( ).y < 600: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) qp.rotate(90) qp.translate(-veh.getPosition().x, -veh.getPosition().y) veh.getPosition().y += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x, veh.getPosition().y - j)) qp.restore() # Already left screen elif veh.getPosition().y >= 600: veh.getPosition().x = 0 veh.getPosition().y = 273 self.beze_t[i] = 0 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x, veh.getPosition().y - j)) # Move horizontal direction(across X_axis) else: veh.getPosition().x += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append( (veh.getPosition().x - j, veh.getPosition().y)) # Vehicle2 # if self.single_0_0: # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # else: try: if self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)] and \ self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)]: self.vehicles_E[0].getPosition().x -= 3 if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) else: qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) except KeyError: self.vehicles_E[0].getPosition().x -= 3 if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] for i in range(270, 330, 10): for j in range(270, 330, 10): self.grid[(i, j)] = True self.ti += 10 if self.ti > 700: self.ti = 0 # print(self.t.elapsed()) self.t.restart()
def on_btn3_2_click(self): video = cv2.VideoCapture('D:/data/featureTracking.mp4') if not video.isOpened(): print('video not found') return w = None prev_img = None tracks = [] t = QTime() t.start() while video.isOpened(): ret, frame = video.read() if ret: gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) if prev_img is not None: prev_pts = np.array([tr[-1] for tr in tracks], dtype=np.float32).reshape(-1, 1, 2) p1, _, _ = cv2.calcOpticalFlowPyrLK( prev_img, gray, prev_pts, None, None, winSize=(21, 21)) p0, _, _ = cv2.calcOpticalFlowPyrLK( gray, prev_img, p1, None, None, winSize=(21, 21)) d = abs(prev_pts - p0).max(-1) prev_img = gray pts = [kp.pt for kp in keypoints] pts = [tuple([int(round(c)) for c in p]) for p in pts] for tr, (x, y), valid in zip(tracks, p1.reshape(-1, 2), d < 50): if not valid: continue tr.append((x, y)) x, y = int(round(x)), int(round(y)) frame = cv2.circle(frame, (x, y), 2, (0, 0, 255), 2) frame = cv2.polylines( frame, [np.int32(tr) for tr in tracks], False, (0, 0, 255), 2) else: detector = self._get_blob_detector() keypoints = detector.detect(frame) pts = [tuple(kp.pt) for kp in keypoints] prev_img = gray tracks = [[p] for p in pts] if w is None: w = ImageWindow(title='3.2 Video tracking', image=frame) w.show() self.addWidget(w) else: w.setImage(frame) w.update() t.restart() while t.elapsed() < 33: QApplication.processEvents() else: break video.release()
class MainWindow(QMainWindow, Ui_MainWindow): """ Class documentation goes here. """ def __init__(self, parent=None): """ Constructor @param parent reference to the parent widget (QWidget) """ super(MainWindow, self).__init__(parent) self.regdialog=DialogRegister() self.setupUi(self) self.arith=None self.preference=DialogPreference() self.timer=QTimer() self.timer.setInterval(10) self.caseIsOpen=False self.labelTotalMark.setText("") self.labelTime.setText("") self.createConnections() self.qtime=QTime() self.timeStart=0 self.timeElapsed=0 self.modeModel=None self.diffiModel=None def createConnections(self): # self.actionNew_Test.triggered.connect(self.on_btnNew_clicked) # self.actionSave.triggered.connect(self.on_actionSave_triggered) # self.btnSave.clicked.connect(self.on_btnSave_clicked) self.tableTestpaper.itemChanged.connect(self.on_tableTestPaper_itemChanged) self.cmbDifficulty.currentIndexChanged.connect(self.on_cmbDifficulty_currentIndexChanged) self.cmbMode.currentIndexChanged.connect(self.on_cmbMode_currentIndexChanged) return def setArith(self,arith): self.arith=arith self.answers=np.zeros(arith.getnTest())+self.arith.smallest self.setDifficulty() self.setMode() if arith.timerOn==False: self.labelTimeName.hide() self.labelTime.hide() self.preference.setArith(arith) return def setMode(self): # only called once for initialization of main window if self.modeModel is None: self.modeModel = QStringListModel() self.cmbMode.setModel(self.modeModel) self.modeModel.setStringList(self.arith.modeTexts[self.arith.diffiLevel]) self.cmbMode.setCurrentIndex(self.arith.mode) return def setDifficulty(self): if self.diffiModel is None: self.diffiModel=QStringListModel() self.cmbDifficulty.setModel(self.diffiModel) self.diffiModel.setStringList(self.arith.difficulties) self.cmbDifficulty.setCurrentIndex(self.arith.diffiLevel) return def on_cmbMode_currentIndexChanged(self): if self.arith: if self.cmbMode.currentIndex()>=0: self.arith.mode=self.cmbMode.currentIndex() else: if self.arith.mode>=len(self.arith.modeTexts[self.arith.diffiLevel]): self.arith.mode=0 self.cmbMode.setCurrentIndex(self.arith.mode) return def on_cmbDifficulty_currentIndexChanged(self): if self.arith: self.arith.diffiLevel=self.cmbDifficulty.currentIndex() if self.modeModel: self.modeModel.setStringList(self.arith.modeTexts[self.arith.diffiLevel]) return @pyqtSlot() def on_tableTestPaper_itemChanged(self): self.caseIsOpen=True return @pyqtSlot() def on_btnNew_clicked(self): """ Slot documentation goes here. """ self.arith.new() self.resetWidgets() return def resetWidgets(self): self.newTestTable() self.updateWindow() self.caseIsOpen=True if self.arith.timerOn: # self.timer.start() self.qtime.restart() return def newTestTable(self): self.tableTestpaper.clear() ncolumn=3*self.arith.nDataColumn self.tableTestpaper.setColumnCount(ncolumn) nTest=self.arith.getnTest() nrow=ceil(nTest/self.arith.nDataColumn) self.tableTestpaper.setRowCount(nrow) self.tableTestpaper.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding) headerLabels=[] for i in range(0,self.arith.nDataColumn): labels=['Expression', 'Answer','Y/N'] headerLabels+=labels self.tableTestpaper.setHorizontalHeaderLabels(headerLabels) self.tableTestpaper.resizeColumnsToContents() self.tableTestpaper.horizontalHeader().setStretchLastSection(True) self.tableTestpaper.horizontalHeader().resizeSections(QHeaderView.Stretch) for k in range(0,3,2): icol=0 for j in range(0,self.arith.nDataColumn): irow=0 for i in range(j,nTest,int(ncolumn/3)): item=QTableWidgetItem() flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled item.setFlags(flags) self.tableTestpaper.setItem(irow,icol+k,item) irow+=1 icol+=3 k=1 icol=0 for j in range(0,self.arith.nDataColumn): irow=0 for i in range(j,nTest,int(ncolumn/3)): # item = QLineEdit() # item.setValidator(QIntValidator(item)) # self.tableTestpaper.setCellWidget(irow, icol+k, item) item=QTableWidgetItem() flags=Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled item.setFlags(flags) self.tableTestpaper.setItem(irow,icol+k,item) irow+=1 icol+=3 return def updateTestPaper(self): ncolumn=3*self.arith.nDataColumn nTest=self.arith.getnTest() icol=0 for j in range(0,self.arith.nDataColumn): irow=0 for i in range(j,nTest,int(ncolumn/3)): self.tableTestpaper.item(irow,icol).setText(self.arith.texts[i]) irow+=1 icol+=3 return def updateWindow(self): self.updateTestPaper() self.updateResultWindow() self.cmbDifficulty.setCurrentIndex(self.arith.diffiLevel) self.cmbMode.setCurrentIndex(self.arith.mode) return def updateResultWindow(self): # TODO: return def getAnswers(self): """ read answer from self.tableTestPaper """ ncolumn=3*self.arith.nDataColumn nTest=self.arith.getnTest() nrow=ceil(nTest/self.arith.nDataColumn) nsp=NumericStringParser() ok=False icol=1 for j in range(0,self.arith.nDataColumn): irow=0 for i in range(j,nTest,int(ncolumn/3)): text=self.tableTestpaper.item(irow,icol).text() # text=self.tableTestpaper.cellWidget(irow,icol).text() if not (text.strip()==str('')): itext=int(text.strip(),10) self.answers[i]=int(text.strip(),10) # goodanswers=nsp.eval(self.tableTestpaper.item(irow,icol-1).text()) # print("%d, %d: %d, %d\n" % (irow,icol,self.answers[i], goodanswers)) irow+=1 icol+=3 return def outputMarkReport(self): self.totalMarks=self.arith.getTotalMark() self.marks=self.arith.getMarks() self.labelTotalMark.setText(str(self.totalMarks)) ncolumn=3*self.arith.nDataColumn nTest=self.arith.getnTest() nrow=ceil(nTest/self.arith.nDataColumn) icol=2 for j in range(0,self.arith.nDataColumn): irow=0 for i in range(j,nTest,int(ncolumn/3)): text=self.tableTestpaper.item(irow,icol-1).text() if (text.strip()==str('')): mark='?' color=Qt.gray elif self.marks[i]==1: mark='Y' #'√' color=Qt.green elif self.marks[i]==0: mark='X' color=Qt.red # item=self.tableTestpaper.item(0,0).s # self.tableTestpaper.item(irow,icol).setBackgroundColor(color) # self.tableTestpaper.item(irow,icol).setBackground(QColor(100,100,150)) self.tableTestpaper.item(irow,icol).setBackground(color) self.tableTestpaper.item(irow,icol).setText(mark) # self.tableTestpaper.item(irow,icol).setWidth(80) irow+=1 icol+=3 if self.arith.timerOn: self.labelTimeName.show() self.labelTime.show() self.labelTime.setText(str(self.timeElapsed)+' sec') return def openFile(self): fname, _ = (QFileDialog.getOpenFileName(self, \ "Open File", "./", \ "CSV File (*.csv);;Text file (*.txt);;All Files (*)")) if not fname: # QMessageBox.information(self, "Unable to open file", # "There was an error opening \"%s\"" % fname) return with open(fname, 'rt',encoding='utf8') as stream: reader = csv.reader(stream,delimiter=',') i=0 for row in reader: if (i==1): self.arith.diffiLevel=int(row[1]) self.arith.mode=int(row[3]) if (i==2): ncol=len(row) self.arith.nDataColumn=int(ncol/3) i+=1 nrowfile=i nrow=i-2 stream.seek(0) i=0 for row in reader: if (i==nrowfile-1): ncol=int(len(row)/3) self.arith.nTest=(nrow-1)*self.arith.nDataColumn+ncol i+=1 self.arith.new() irow=0 i=0 stream.seek(0) for row in reader: if (irow>=2): if irow<nrowfile-1: ncol1=self.arith.nDataColumn else: ncol1=int(len(row)/3) icol=0 for j in range(icol,len(row),3): text=row[j] self.arith.texts[i]=text i+=1 irow+=1 self.arith.calcResults() self.resetWidgets() return def saveFile(self): fname, _ = (QFileDialog.getSaveFileName(self, \ "Save File As", "./", \ "CSV File (*.csv);;Text file (*.txt);;All Files (*)")) #??? if not fname: # QMessageBox.information(self, "Unable to open file", # "There was an error opening \"%s\"" % fname) return with open((fname), 'wt',encoding='utf8') as stream: writer = csv.writer(stream) writer.writerow(['Marks:', str(self.totalMarks), 'Elapsed time(sec): ', str(self.timeElapsed)]) writer.writerow(['Difficulty: ',self.arith.diffiLevel,'Mode: ', self.arith.mode]) for row in range(0,self.tableTestpaper.rowCount()): rowdata = [] for column in range(self.tableTestpaper.columnCount()): item = self.tableTestpaper.item(row, column) # item is not None or if item.text() is not str(''): rowdata.append( (item.text()))#.encode('utf8')) else: rowdata.append(str('N/A')) writer.writerow(rowdata) self.caseIsOpen=False return @pyqtSlot() def on_btnReset_clicked(self): """ Slot documentation goes here. """ self.arith.reset() self.updateWindow() return @pyqtSlot() def on_btnSave_clicked(self): """ Slot documentation goes here. """ if not self.arith.empty: self.saveFile() else: QMessageBox.information(self, "Unable to save file", "The test paper is still empty" ) return @pyqtSlot() def on_btnMark_clicked(self): """ Slot documentation goes here. """ if self.arith.timerOn: # self.timer.stop() self.timeElapsed=float(self.qtime.elapsed())/1000.0 self.getAnswers() self.arith.mark(self.answers) self.outputMarkReport() return @pyqtSlot() def on_btnStop_clicked(self): """ Slot documentation goes here. """ # TODO: not implemented yet self.timer.stop() return @pyqtSlot() def on_btnQuit_clicked(self): """ Slot documentation goes here. """ if(self.caseIsOpen==False): QCoreApplication.instance().quit() else: reply = QMessageBox.question(self, 'Warning', "Test not saved. Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: QCoreApplication.instance().quit() # else: # event.ignore() return @pyqtSlot() def on_btnOpen_clicked(self): """ Slot documentation goes here. """ self.openFile() return @pyqtSlot() def on_actionOpen_triggered(self): """ Slot documentation goes here. """ self.openFile() return @pyqtSlot() def on_actionSave_triggered(self): """ Slot documentation goes here. """ if not self.arith.empty: self.saveFile() else: QMessageBox.information(self, "Unable to save file", "The test paper is still empty" ) return @pyqtSlot() def on_actionPreferences_triggered(self): """ Slot documentation goes here. """ self.preference.showArith() if self.preference.exec_()==QDialog.Accepted: self.answers=np.zeros(self.arith.getnTest())+self.arith.smallest if not self.arith.timerOn: self.labelTimeName.hide() self.labelTime.hide() else: self.labelTimeName.show() return @pyqtSlot() def on_actionAbout_triggered(self): """ Slot documentation goes here. """ QMessageBox.information(self, "About Arith", __arith_title__) return @pyqtSlot() def on_actionNew_Test_triggered(self): """ Slot documentation goes here. """ # TODO: not implemented yet self.on_btnNew_clicked() return @pyqtSlot() def on_actionQuit_triggered(self): """ Slot documentation goes here. """ QCoreApplication.instance().quit() return @pyqtSlot() def on_actionReset_triggered(self): """ Slot documentation goes here. """ self.arith.reset() self.updateWindow() return @pyqtSlot() def on_actionMark_triggered(self): """ Slot documentation goes here. """ self.on_btnMark_clicked() return @pyqtSlot() def on_actionRegister_triggered(self): if self.regdialog.exec_()==QDialog.Accepted: print('reg OK') # else: return
class StatusBar(QWidget): """The statusbar at the bottom of the mainwindow. Attributes: txt: The Text widget in the statusbar. keystring: The KeyString widget in the statusbar. percentage: The Percentage widget in the statusbar. url: The UrlText widget in the statusbar. prog: The Progress widget in the statusbar. cmd: The Command widget in the statusbar. _hbox: The main QHBoxLayout. _stack: The QStackedLayout with cmd/txt widgets. _text_queue: A deque of (error, text) tuples to be displayed. error: True if message is an error, False otherwise _text_pop_timer: A Timer displaying the error messages. _stopwatch: A QTime for the last displayed message. _timer_was_active: Whether the _text_pop_timer was active before hiding the command widget. _previous_widget: A PreviousWidget member - the widget which was displayed when an error interrupted it. _win_id: The window ID the statusbar is associated with. Class attributes: _severity: The severity of the current message, a Severity member. For some reason we need to have this as class attribute so pyqtProperty works correctly. _prompt_active: If we're currently in prompt-mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _insert_active: If we're currently in insert mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _command_active: If we're currently in command mode. For some reason we need to have this as class attribute so pyqtProperty works correctly. _caret_mode: The current caret mode (off/on/selection). For some reason we need to have this as class attribute so pyqtProperty works correctly. Signals: resized: Emitted when the statusbar has resized, so the completion widget can adjust its size to it. arg: The new size. moved: Emitted when the statusbar has moved, so the completion widget can move to the right position. arg: The new position. """ resized = pyqtSignal('QRect') moved = pyqtSignal('QPoint') _severity = None _prompt_active = False _insert_active = False _command_active = False _caret_mode = CaretMode.off STYLESHEET = """ QWidget#StatusBar, QWidget#StatusBar QLabel, QWidget#StatusBar QLineEdit { font: {{ font['statusbar'] }}; background-color: {{ color['statusbar.bg'] }}; color: {{ color['statusbar.fg'] }}; } QWidget#StatusBar[caret_mode="on"], QWidget#StatusBar[caret_mode="on"] QLabel, QWidget#StatusBar[caret_mode="on"] QLineEdit { color: {{ color['statusbar.fg.caret'] }}; background-color: {{ color['statusbar.bg.caret'] }}; } QWidget#StatusBar[caret_mode="selection"], QWidget#StatusBar[caret_mode="selection"] QLabel, QWidget#StatusBar[caret_mode="selection"] QLineEdit { color: {{ color['statusbar.fg.caret-selection'] }}; background-color: {{ color['statusbar.bg.caret-selection'] }}; } QWidget#StatusBar[severity="error"], QWidget#StatusBar[severity="error"] QLabel, QWidget#StatusBar[severity="error"] QLineEdit { color: {{ color['statusbar.fg.error'] }}; background-color: {{ color['statusbar.bg.error'] }}; } QWidget#StatusBar[severity="warning"], QWidget#StatusBar[severity="warning"] QLabel, QWidget#StatusBar[severity="warning"] QLineEdit { color: {{ color['statusbar.fg.warning'] }}; background-color: {{ color['statusbar.bg.warning'] }}; } QWidget#StatusBar[prompt_active="true"], QWidget#StatusBar[prompt_active="true"] QLabel, QWidget#StatusBar[prompt_active="true"] QLineEdit { color: {{ color['statusbar.fg.prompt'] }}; background-color: {{ color['statusbar.bg.prompt'] }}; } QWidget#StatusBar[insert_active="true"], QWidget#StatusBar[insert_active="true"] QLabel, QWidget#StatusBar[insert_active="true"] QLineEdit { color: {{ color['statusbar.fg.insert'] }}; background-color: {{ color['statusbar.bg.insert'] }}; } QWidget#StatusBar[command_active="true"], QWidget#StatusBar[command_active="true"] QLabel, QWidget#StatusBar[command_active="true"] QLineEdit { color: {{ color['statusbar.fg.command'] }}; background-color: {{ color['statusbar.bg.command'] }}; } """ def __init__(self, win_id, parent=None): super().__init__(parent) objreg.register('statusbar', self, scope='window', window=win_id) self.setObjectName(self.__class__.__name__) self.setAttribute(Qt.WA_StyledBackground) style.set_register_stylesheet(self) self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self._win_id = win_id self._option = None self._stopwatch = QTime() self._hbox = QHBoxLayout(self) self.set_hbox_padding() objreg.get('config').changed.connect(self.set_hbox_padding) self._hbox.setSpacing(5) self._stack = QStackedLayout() self._hbox.addLayout(self._stack) self._stack.setContentsMargins(0, 0, 0, 0) self.cmd = command.Command(win_id) self._stack.addWidget(self.cmd) objreg.register('status-command', self.cmd, scope='window', window=win_id) self.txt = textwidget.Text() self._stack.addWidget(self.txt) self._timer_was_active = False self._text_queue = collections.deque() self._text_pop_timer = usertypes.Timer(self, 'statusbar_text_pop') self._text_pop_timer.timeout.connect(self._pop_text) self.set_pop_timer_interval() objreg.get('config').changed.connect(self.set_pop_timer_interval) self.prompt = prompt.Prompt(win_id) self._stack.addWidget(self.prompt) self._previous_widget = PreviousWidget.none self.cmd.show_cmd.connect(self._show_cmd_widget) self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() prompter = objreg.get('prompter', scope='window', window=self._win_id) prompter.show_prompt.connect(self._show_prompt_widget) prompter.hide_prompt.connect(self._hide_prompt_widget) self._hide_prompt_widget() self.keystring = keystring.KeyString() self._hbox.addWidget(self.keystring) self.url = url.UrlText() self._hbox.addWidget(self.url) self.percentage = percentage.Percentage() self._hbox.addWidget(self.percentage) self.tabindex = tabindex.TabIndex() self._hbox.addWidget(self.tabindex) # We add a parent to Progress here because it calls self.show() based # on some signals, and if that happens before it's added to the layout, # it will quickly blink up as independent window. self.prog = progress.Progress(self) self._hbox.addWidget(self.prog) objreg.get('config').changed.connect(self.maybe_hide) QTimer.singleShot(0, self.maybe_hide) def __repr__(self): return utils.get_repr(self) @config.change_filter('ui', 'hide-statusbar') def maybe_hide(self): """Hide the statusbar if it's configured to do so.""" hide = config.get('ui', 'hide-statusbar') if hide: self.hide() else: self.show() @config.change_filter('ui', 'statusbar-padding') def set_hbox_padding(self): padding = config.get('ui', 'statusbar-padding') self._hbox.setContentsMargins(padding.left, 0, padding.right, 0) @pyqtProperty(str) def severity(self): """Getter for self.severity, so it can be used as Qt property. Return: The severity as a string (!) """ if self._severity is None: return "" else: return self._severity.name def _set_severity(self, severity): """Set the severity for the current message. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. Args: severity: A Severity member. """ if self._severity == severity: # This gets called a lot (e.g. if the completion selection was # changed), and setStyleSheet is relatively expensive, so we ignore # this if there's nothing to change. return log.statusbar.debug("Setting severity to {}".format(severity)) self._severity = severity self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) if severity != Severity.normal: # If we got an error while command/prompt was shown, raise the text # widget. self._stack.setCurrentWidget(self.txt) @pyqtProperty(bool) def prompt_active(self): """Getter for self.prompt_active, so it can be used as Qt property.""" return self._prompt_active def _set_prompt_active(self, val): """Setter for self.prompt_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ log.statusbar.debug("Setting prompt_active to {}".format(val)) self._prompt_active = val self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) @pyqtProperty(bool) def command_active(self): """Getter for self.command_active, so it can be used as Qt property.""" return self._command_active @pyqtProperty(bool) def insert_active(self): """Getter for self.insert_active, so it can be used as Qt property.""" return self._insert_active @pyqtProperty(str) def caret_mode(self): """Getter for self._caret_mode, so it can be used as Qt property.""" return self._caret_mode.name def set_mode_active(self, mode, val): """Setter for self.{insert,command,caret}_active. Re-set the stylesheet after setting the value, so everything gets updated by Qt properly. """ if mode == usertypes.KeyMode.insert: log.statusbar.debug("Setting insert_active to {}".format(val)) self._insert_active = val if mode == usertypes.KeyMode.command: log.statusbar.debug("Setting command_active to {}".format(val)) self._command_active = val elif mode == usertypes.KeyMode.caret: webview = objreg.get('tabbed-browser', scope='window', window=self._win_id).currentWidget() log.statusbar.debug("Setting caret_mode - val {}, selection " "{}".format(val, webview.selection_enabled)) if val: if webview.selection_enabled: self._set_mode_text("{} selection".format(mode.name)) self._caret_mode = CaretMode.selection else: self._set_mode_text(mode.name) self._caret_mode = CaretMode.on else: self._caret_mode = CaretMode.off self.setStyleSheet(style.get_stylesheet(self.STYLESHEET)) def _set_mode_text(self, mode): """Set the mode text.""" text = "-- {} MODE --".format(mode.upper()) self.txt.set_text(self.txt.Text.normal, text) def _pop_text(self): """Display a text in the statusbar and pop it from _text_queue.""" try: severity, text = self._text_queue.popleft() except IndexError: self._set_severity(Severity.normal) self.txt.set_text(self.txt.Text.temp, '') self._text_pop_timer.stop() # If a previous widget was interrupted by an error, restore it. if self._previous_widget == PreviousWidget.prompt: self._stack.setCurrentWidget(self.prompt) elif self._previous_widget == PreviousWidget.command: self._stack.setCurrentWidget(self.cmd) elif self._previous_widget == PreviousWidget.none: self.maybe_hide() else: raise AssertionError("Unknown _previous_widget!") return self.show() log.statusbar.debug("Displaying message: {} (severity {})".format( text, severity)) log.statusbar.debug("Remaining: {}".format(self._text_queue)) self._set_severity(severity) self.txt.set_text(self.txt.Text.temp, text) def _show_cmd_widget(self): """Show command widget instead of temporary text.""" self._set_severity(Severity.normal) self._previous_widget = PreviousWidget.command if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.cmd) self.show() def _hide_cmd_widget(self): """Show temporary text instead of command widget.""" log.statusbar.debug("Hiding cmd widget, queue: {}".format( self._text_queue)) self._previous_widget = PreviousWidget.none if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) self.maybe_hide() def _show_prompt_widget(self): """Show prompt widget instead of temporary text.""" if self._stack.currentWidget() is self.prompt: return self._set_severity(Severity.normal) self._set_prompt_active(True) self._previous_widget = PreviousWidget.prompt if self._text_pop_timer.isActive(): self._timer_was_active = True self._text_pop_timer.stop() self._stack.setCurrentWidget(self.prompt) self.show() def _hide_prompt_widget(self): """Show temporary text instead of prompt widget.""" self._set_prompt_active(False) self._previous_widget = PreviousWidget.none log.statusbar.debug("Hiding prompt widget, queue: {}".format( self._text_queue)) if self._timer_was_active: # Restart the text pop timer if it was active before hiding. self._pop_text() self._text_pop_timer.start() self._timer_was_active = False self._stack.setCurrentWidget(self.txt) self.maybe_hide() def _disp_text(self, text, severity, immediately=False): """Inner logic for disp_error and disp_temp_text. Args: text: The message to display. severity: The severity of the messages. immediately: If set, message gets displayed immediately instead of queued. """ log.statusbar.debug("Displaying text: {} (severity={})".format( text, severity)) mindelta = config.get('ui', 'message-timeout') if self._stopwatch.isNull(): delta = None self._stopwatch.start() else: delta = self._stopwatch.restart() log.statusbar.debug("queue: {} / delta: {}".format( self._text_queue, delta)) if not self._text_queue and (delta is None or delta > mindelta): # If the queue is empty and we didn't print messages for long # enough, we can take the short route and display the message # immediately. We then start the pop_timer only to restore the # normal state in 2 seconds. log.statusbar.debug("Displaying immediately") self._set_severity(severity) self.show() self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() elif self._text_queue and self._text_queue[-1] == (severity, text): # If we get the same message multiple times in a row and we're # still displaying it *anyways* we ignore the new one log.statusbar.debug("ignoring") elif immediately: # This message is a reaction to a keypress and should be displayed # immediately, temporarily interrupting the message queue. # We display this immediately and restart the timer.to clear it and # display the rest of the queue later. log.statusbar.debug("Moving to beginning of queue") self._set_severity(severity) self.show() self.txt.set_text(self.txt.Text.temp, text) self._text_pop_timer.start() else: # There are still some messages to be displayed, so we queue this # up. log.statusbar.debug("queueing") self._text_queue.append((severity, text)) self._text_pop_timer.start() @pyqtSlot(str, bool) def disp_error(self, text, immediately=False): """Display an error in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.error, immediately) @pyqtSlot(str, bool) def disp_warning(self, text, immediately=False): """Display a warning in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.warning, immediately) @pyqtSlot(str, bool) def disp_temp_text(self, text, immediately): """Display a temporary text in the statusbar. Args: text: The message to display. immediately: If set, message gets displayed immediately instead of queued. """ self._disp_text(text, Severity.normal, immediately) @pyqtSlot(str) def set_text(self, val): """Set a normal (persistent) text in the status bar.""" self.txt.set_text(self.txt.Text.normal, val) @pyqtSlot(usertypes.KeyMode) def on_mode_entered(self, mode): """Mark certain modes in the commandline.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[mode].passthrough: self._set_mode_text(mode.name) if mode in (usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret): self.set_mode_active(mode, True) @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode) def on_mode_left(self, old_mode, new_mode): """Clear marked mode.""" keyparsers = objreg.get('keyparsers', scope='window', window=self._win_id) if keyparsers[old_mode].passthrough: if keyparsers[new_mode].passthrough: self._set_mode_text(new_mode.name) else: self.txt.set_text(self.txt.Text.normal, '') if old_mode in (usertypes.KeyMode.insert, usertypes.KeyMode.command, usertypes.KeyMode.caret): self.set_mode_active(old_mode, False) @config.change_filter('ui', 'message-timeout') def set_pop_timer_interval(self): """Update message timeout when config changed.""" self._text_pop_timer.setInterval(config.get('ui', 'message-timeout')) def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. Args: e: The QResizeEvent. """ super().resizeEvent(e) self.resized.emit(self.geometry()) def moveEvent(self, e): """Extend moveEvent of QWidget to emit a moved signal afterwards. Args: e: The QMoveEvent. """ super().moveEvent(e) self.moved.emit(e.pos()) def minimumSizeHint(self): """Set the minimum height to the text height plus some padding.""" padding = config.get('ui', 'statusbar-padding') width = super().minimumSizeHint().width() height = self.fontMetrics().height() + padding.top + padding.bottom return QSize(width, height)
class MainWindow(QGraphicsView): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.updateTimer = QTimer(self) self.demoStartTime = QTime() self.fpsTime = QTime() self.background = QPixmap() self.scene = None self.mainSceneRoot = None self.frameTimeList = [] self.fpsHistory = [] self.currentFps = Colors.fps self.fpsMedian = -1 self.fpsLabel = None self.pausedLabel = None self.doneAdapt = False self.useTimer = False self.updateTimer.setSingleShot(True) self.companyLogo = None self.qtLogo = None self.setupWidget() self.setupScene() self.setupSceneItems() self.drawBackgroundToPixmap() def setupWidget(self): desktop = QApplication.desktop() screenRect = desktop.screenGeometry(desktop.primaryScreen()) windowRect = QRect(0, 0, 800, 600) if screenRect.width() < 800: windowRect.setWidth(screenRect.width()) if screenRect.height() < 600: windowRect.setHeight(screenRect.height()) windowRect.moveCenter(screenRect.center()) self.setGeometry(windowRect) self.setMinimumSize(80, 60) self.setWindowTitle("PyQt Examples") self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setFrameStyle(QFrame.NoFrame) self.setRenderingSystem() self.updateTimer.timeout.connect(self.tick) def setRenderingSystem(self): self.setCacheMode(QGraphicsView.CacheBackground) self.setViewport(QWidget()) def start(self): self.switchTimerOnOff(True) self.demoStartTime.restart() MenuManager.instance().itemSelected(MenuManager.ROOT, Colors.rootMenuName) Colors.debug("- starting demo") def enableMask(self, enable): if not enable or Colors.noWindowMask: self.clearMask() else: region = QPolygon([ # North side. 0, 0, 800, 0, # East side. # 800, 70, # 790, 90, # 790, 480, # 800, 500, 800, 600, # South side. 700, 600, 670, 590, 130, 590, 100, 600, 0, 600, # West side. # 0, 550, # 10, 530, # 10, 520, # 0, 520, 0, 0]) self.setMask(QRegion(region)) def setupScene(self): self.scene = QGraphicsScene(self) self.scene.setSceneRect(0, 0, 800, 600) self.setScene(self.scene) self.scene.setItemIndexMethod(QGraphicsScene.NoIndex) def switchTimerOnOff(self, on): ticker = MenuManager.instance().ticker if ticker and ticker.scene(): ticker.tickOnPaint = not on or Colors.noTimerUpdate if on and not Colors.noTimerUpdate: self.useTimer = True self.fpsTime = QTime.currentTime() self.updateTimer.start(int(1000 / Colors.fps)) update_mode = QGraphicsView.NoViewportUpdate else: self.useTimer = False self.updateTimer.stop() if Colors.noTicker: update_mode = QGraphicsView.MinimalViewportUpdate else: update_mode = QGraphicsView.SmartViewportUpdate self.setViewportUpdateMode(update_mode) def measureFps(self): # Calculate time difference. t = self.fpsTime.msecsTo(QTime.currentTime()) if t == 0: t = 0.01 self.currentFps = (1000.0 / t) self.fpsHistory.append(self.currentFps) self.fpsTime = QTime.currentTime() # Calculate median. size = len(self.fpsHistory) if size == 10: self.fpsHistory.sort() self.fpsMedian = self.fpsHistory[int(size / 2)] if self.fpsMedian == 0: self.fpsMedian = 0.01 self.fpsHistory = [] return True return False def forceFpsMedianCalculation(self): # Used for adaption in case things are so slow that no median has yet # been calculated. if self.fpsMedian != -1: return size = len(self.fpsHistory) if size == 0: self.fpsMedian = 0.01 return self.fpsHistory.sort() self.fpsMedian = self.fpsHistory[size // 2] if self.fpsMedian == 0: self.fpsMedian = 0.01 def tick(self): medianChanged = self.measureFps() self.checkAdapt() if medianChanged and self.fpsLabel and Colors.showFps: self.fpsLabel.setText("FPS: %d" % int(self.currentFps)) if MenuManager.instance().ticker: MenuManager.instance().ticker.tick() self.viewport().update() if self.useTimer: self.updateTimer.start(int(1000 / Colors.fps)) def setupSceneItems(self): if Colors.showFps: self.fpsLabel = DemoTextItem("FPS: --", Colors.buttonFont(), Qt.white, -1, None, DemoTextItem.DYNAMIC_TEXT) self.fpsLabel.setZValue(1000) self.fpsLabel.setPos(Colors.stageStartX, 600 - QFontMetricsF(Colors.buttonFont()).height() - 5) self.mainSceneRoot = QGraphicsWidget() self.scene.addItem(self.mainSceneRoot) self.companyLogo = ImageItem(QImage(':/images/trolltech-logo.png'), 1000, 1000, None, True, 0.5) self.qtLogo = ImageItem(QImage(':/images/qtlogo_small.png'), 1000, 1000, None, True, 0.5) self.companyLogo.setZValue(100) self.qtLogo.setZValue(100) self.pausedLabel = DemoTextItem("PAUSED", Colors.buttonFont(), Qt.white, -1, None) self.pausedLabel.setZValue(100) fm = QFontMetricsF(Colors.buttonFont()) self.pausedLabel.setPos(Colors.stageWidth - fm.width("PAUSED"), 590 - fm.height()) self.pausedLabel.setRecursiveVisible(False) def checkAdapt(self): if self.doneAdapt or Colors.noTimerUpdate or self.demoStartTime.elapsed() < 2000: return self.doneAdapt = True self.forceFpsMedianCalculation() Colors.benchmarkFps = self.fpsMedian Colors.debug("- benchmark: %d FPS" % int(Colors.benchmarkFps)) if Colors.noAdapt: return if self.fpsMedian < 30: ticker = MenuManager.instance().ticker if ticker and ticker.scene(): self.scene.removeItem(ticker) Colors.noTimerUpdate = True self.switchTimerOnOff(False) if self.fpsLabel: self.fpsLabel.setText("FPS: (%d)" % int(self.fpsMedian)) Colors.debug("- benchmark adaption: removed ticker (fps < 30)") if self.fpsMedian < 20: Colors.noAnimations = True Colors.debug("- benchmark adaption: animations switched off (fps < 20)") Colors.adapted = True def drawBackgroundToPixmap(self): r = self.scene.sceneRect() self.background = QPixmap(qRound(r.width()), qRound(r.height())) self.background.fill(Qt.black) painter = QPainter(self.background) bg = QImage(':/images/demobg.png') painter.drawImage(0, 0, bg) def drawBackground(self, painter, rect): painter.drawPixmap(QPoint(0, 0), self.background) def toggleFullscreen(self): if self.isFullScreen(): self.enableMask(True) self.showNormal() if MenuManager.instance().ticker: MenuManager.instance().ticker.pause(False) else: self.enableMask(False) self.showFullScreen() def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: QApplication.quit() elif event.key() == Qt.Key_F1: s = "" s += "\nAdapt: " s += ["on", "off"][Colors.noAdapt] s += "\nAdaption occured: " s += ["no", "yes"][Colors.adapted] w = QWidget() s += "\nColor bit depth: %d" % w.depth() s += "\nWanted FPS: %d" % Colors.fps s += "\nBenchmarked FPS: "; if Colors.benchmarkFps != -1: s += "%d" % Colors.benchmarkFps else: s += "not calculated" s += "\nAnimations: "; s += ["on", "off"][Colors.noAnimations] s += "\nBlending: "; s += ["on", "off"][Colors.useEightBitPalette] s += "\nTicker: "; s += ["on", "off"][Colors.noTicker] s += "\nPixmaps: "; s += ["off", "on"][Colors.usePixmaps] s += "\nRescale images on resize: "; s += ["on", "off"][Colors.noRescale] s += "\nTimer based updates: "; s += ["on", "off"][Colors.noTimerUpdate] s += "\nSeparate loop: "; s += ["no", "yes"][Colors.useLoop] s += "\nScreen sync: "; s += ["yes", "no"][Colors.noScreenSync] QMessageBox.information(None, "Current configuration", s) super(MainWindow, self).keyPressEvent(event) def focusInEvent(self, event): if not Colors.pause: return if MenuManager.instance().ticker: MenuManager.instance().ticker.pause(False) code = MenuManager.instance().currentMenuCode if code in (MenuManager.ROOT, MenuManager.MENU1): self.switchTimerOnOff(True) self.pausedLabel.setRecursiveVisible(False) def focusOutEvent(self, event): if not Colors.pause: return if MenuManager.instance().ticker: MenuManager.instance().ticker.pause(True) code = MenuManager.instance().currentMenuCode if code in (MenuManager.ROOT, MenuManager.MENU1): self.switchTimerOnOff(False) self.pausedLabel.setRecursiveVisible(True) def resizeEvent(self, event): self.resetTransform() self.scale(event.size().width() / 800.0, event.size().height() / 600.0) super(MainWindow, self).resizeEvent(event) DemoItem.setTransform(self.transform()) if self.companyLogo: r = self.scene.sceneRect() ttb = self.companyLogo.boundingRect() self.companyLogo.setPos(int((r.width() - ttb.width()) / 2), 595 - ttb.height()) qtb = self.qtLogo.boundingRect() self.qtLogo.setPos(802 - qtb.width(), 0) # Changing size will almost always hurt FPS during the change so ignore # it. self.fpsHistory = []
class Connection(QTcpSocket): """ Class representing a peer connection. @signal readyForUse() emitted when the connection is ready for use @signal newMessage(user, message) emitted after a new message has arrived (string, string) @signal getParticipants() emitted after a get participants message has arrived @signal participants(participants) emitted after the list of participants has arrived (list of strings of "host:port") """ WaitingForGreeting = 0 ReadingGreeting = 1 ReadyForUse = 2 PlainText = 0 Ping = 1 Pong = 2 Greeting = 3 GetParticipants = 4 Participants = 5 Editor = 6 Undefined = 99 ProtocolMessage = "MESSAGE" ProtocolPing = "PING" ProtocolPong = "PONG" ProtocolGreeting = "GREETING" ProtocolGetParticipants = "GET_PARTICIPANTS" ProtocolParticipants = "PARTICIPANTS" ProtocolEditor = "EDITOR" readyForUse = pyqtSignal() newMessage = pyqtSignal(str, str) getParticipants = pyqtSignal() participants = pyqtSignal(list) editorCommand = pyqtSignal(str, str, str) rejected = pyqtSignal(str) def __init__(self, parent=None): """ Constructor @param parent referenec to the parent object (QObject) """ super(Connection, self).__init__(parent) self.__greetingMessage = self.tr("undefined") self.__username = self.tr("unknown") self.__serverPort = 0 self.__state = Connection.WaitingForGreeting self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = -1 self.__transferTimerId = 0 self.__isGreetingMessageSent = False self.__pingTimer = QTimer(self) self.__pingTimer.setInterval(PingInterval) self.__pongTime = QTime() self.__buffer = QByteArray() self.__client = None self.readyRead.connect(self.__processReadyRead) self.disconnected.connect(self.__disconnected) self.__pingTimer.timeout.connect(self.__sendPing) self.connected.connect(self.__sendGreetingMessage) def name(self): """ Public method to get the connection name. @return connection name (string) """ return self.__username def serverPort(self): """ Public method to get the server port. @return server port (integer) """ return self.__serverPort def setClient(self, client): """ Public method to set the reference to the cooperation client. @param client reference to the cooperation client (CooperationClient) """ self.__client = client def setGreetingMessage(self, message, serverPort): """ Public method to set the greeting message. @param message greeting message (string) @param serverPort port number to include in the message (integer) """ self.__greetingMessage = "{0}:{1}".format(message, serverPort) def sendMessage(self, message): """ Public method to send a message. @param message message to be sent (string) @return flag indicating a successful send (boolean) """ if message == "": return False msg = QByteArray(message.encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolMessage, SeparatorToken, msg.size()).encode("utf-8")) + msg return self.write(data) == data.size() def timerEvent(self, evt): """ Protected method to handle timer events. @param evt reference to the timer event (QTimerEvent) """ if evt.timerId() == self.__transferTimerId: self.abort() self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 def __processReadyRead(self): """ Private slot to handle the readyRead signal. """ if self.__state == Connection.WaitingForGreeting: if not self.__readProtocolHeader(): return if self.__currentDataType != Connection.Greeting: self.abort() return self.__state = Connection.ReadingGreeting if self.__state == Connection.ReadingGreeting: if not self.__hasEnoughData(): return self.__buffer = QByteArray( self.read(self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return try: user, serverPort = \ str(self.__buffer, encoding="utf-8").split(":") except ValueError: self.abort() return self.__serverPort = int(serverPort) hostInfo = QHostInfo.fromName(self.peerAddress().toString()) self.__username = "******".format(user, hostInfo.hostName(), self.peerPort()) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() if not self.isValid(): self.abort() return bannedName = "{0}@{1}".format( user, hostInfo.hostName(), ) Preferences.syncPreferences() if bannedName in Preferences.getCooperation("BannedUsers"): self.rejected.emit( self.tr("* Connection attempted by banned user '{0}'."). format(bannedName)) self.abort() return if self.__serverPort != self.peerPort() and \ not Preferences.getCooperation("AutoAcceptConnections"): # don't ask for reverse connections or # if we shall accept automatically res = E5MessageBox.yesNo( None, self.tr("New Connection"), self.tr("""<p>Accept connection from """ """<strong>{0}@{1}</strong>?</p>""").format( user, hostInfo.hostName()), yesDefault=True) if not res: self.abort() return if self.__client is not None: chatWidget = self.__client.chatWidget() if chatWidget is not None and not chatWidget.isVisible(): e5App().getObject( "UserInterface").activateCooperationViewer() if not self.__isGreetingMessageSent: self.__sendGreetingMessage() self.__pingTimer.start() self.__pongTime.start() self.__state = Connection.ReadyForUse self.readyForUse.emit() while self.bytesAvailable(): if self.__currentDataType == Connection.Undefined: if not self.__readProtocolHeader(): return if not self.__hasEnoughData(): return self.__processData() def __sendPing(self): """ Private slot to send a ping message. """ if self.__pongTime.elapsed() > PongTimeout: self.abort() return self.write("{0}{1}1{1}p".format(Connection.ProtocolPing, SeparatorToken)) def __sendGreetingMessage(self): """ Private slot to send a greeting message. """ greeting = QByteArray(self.__greetingMessage.encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolGreeting, SeparatorToken, greeting.size()).encode("utf-8")) + greeting if self.write(data) == data.size(): self.__isGreetingMessageSent = True def __readDataIntoBuffer(self, maxSize=MaxBufferSize): """ Private method to read some data into the buffer. @param maxSize maximum size of data to read (integer) @return size of data read (integer) """ if maxSize > MaxBufferSize: return 0 numBytesBeforeRead = self.__buffer.size() if numBytesBeforeRead == MaxBufferSize: self.abort() return 0 while self.bytesAvailable() and self.__buffer.size() < maxSize: self.__buffer.append(self.read(1)) if self.__buffer.endsWith(SeparatorToken): break return self.__buffer.size() - numBytesBeforeRead def __dataLengthForCurrentDataType(self): """ Private method to get the data length for the current data type. @return data length (integer) """ if self.bytesAvailable() <= 0 or \ self.__readDataIntoBuffer() <= 0 or \ not self.__buffer.endsWith(SeparatorToken): return 0 self.__buffer.chop(len(SeparatorToken)) number = self.__buffer.toInt()[0] self.__buffer.clear() return number def __readProtocolHeader(self): """ Private method to read the protocol header. @return flag indicating a successful read (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__readDataIntoBuffer() <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False self.__buffer.chop(len(SeparatorToken)) if self.__buffer == Connection.ProtocolPing: self.__currentDataType = Connection.Ping elif self.__buffer == Connection.ProtocolPong: self.__currentDataType = Connection.Pong elif self.__buffer == Connection.ProtocolMessage: self.__currentDataType = Connection.PlainText elif self.__buffer == Connection.ProtocolGreeting: self.__currentDataType = Connection.Greeting elif self.__buffer == Connection.ProtocolGetParticipants: self.__currentDataType = Connection.GetParticipants elif self.__buffer == Connection.ProtocolParticipants: self.__currentDataType = Connection.Participants elif self.__buffer == Connection.ProtocolEditor: self.__currentDataType = Connection.Editor else: self.__currentDataType = Connection.Undefined self.abort() return False self.__buffer.clear() self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() return True def __hasEnoughData(self): """ Private method to check, if enough data is available. @return flag indicating availability of enough data (boolean) """ if self.__transferTimerId: self.killTimer(self.__transferTimerId) self.__transferTimerId = 0 if self.__numBytesForCurrentDataType <= 0: self.__numBytesForCurrentDataType = \ self.__dataLengthForCurrentDataType() if self.bytesAvailable() < self.__numBytesForCurrentDataType or \ self.__numBytesForCurrentDataType <= 0: self.__transferTimerId = self.startTimer(TransferTimeout) return False return True def __processData(self): """ Private method to process the received data. """ self.__buffer = QByteArray(self.read( self.__numBytesForCurrentDataType)) if self.__buffer.size() != self.__numBytesForCurrentDataType: self.abort() return if self.__currentDataType == Connection.PlainText: self.newMessage.emit(self.__username, str(self.__buffer, encoding="utf-8")) elif self.__currentDataType == Connection.Ping: self.write("{0}{1}1{1}p".format(Connection.ProtocolPong, SeparatorToken)) elif self.__currentDataType == Connection.Pong: self.__pongTime.restart() elif self.__currentDataType == Connection.GetParticipants: self.getParticipants.emit() elif self.__currentDataType == Connection.Participants: msg = str(self.__buffer, encoding="utf-8") if msg == "<empty>": participantsList = [] else: participantsList = msg.split(SeparatorToken) self.participants.emit(participantsList[:]) elif self.__currentDataType == Connection.Editor: hash, fn, msg = \ str(self.__buffer, encoding="utf-8").split(SeparatorToken) self.editorCommand.emit(hash, fn, msg) self.__currentDataType = Connection.Undefined self.__numBytesForCurrentDataType = 0 self.__buffer.clear() def sendGetParticipants(self): """ Public method to request a list of participants. """ self.write("{0}{1}1{1}l".format(Connection.ProtocolGetParticipants, SeparatorToken)) def sendParticipants(self, participants): """ Public method to send the list of participants. @param participants list of participants (list of strings of "host:port") """ if participants: message = SeparatorToken.join(participants) else: message = "<empty>" msg = QByteArray(message.encode("utf-8")) data = QByteArray("{0}{1}{2}{1}".format( Connection.ProtocolParticipants, SeparatorToken, msg.size()).encode("utf-8")) + msg self.write(data) def sendEditorCommand(self, projectHash, filename, message): """ Public method to send an editor command. @param projectHash hash of the project (string) @param filename project relative universal file name of the sending editor (string) @param message editor command to be sent (string) """ msg = QByteArray("{0}{1}{2}{1}{3}".format(projectHash, SeparatorToken, filename, message).encode("utf-8")) data = QByteArray( "{0}{1}{2}{1}".format(Connection.ProtocolEditor, SeparatorToken, msg.size()).encode("utf-8")) + msg self.write(data) def __disconnected(self): """ Private slot to handle the connection being dropped. """ self.__pingTimer.stop() if self.__state == Connection.WaitingForGreeting: self.rejected.emit( self.tr("* Connection to {0}:{1} refused.").format( self.peerName(), self.peerPort()))
class Example(QWidget): def __init__(self, vehicles_N, vehicles_W, vehicles_E, sendData_1, sendData_3): super().__init__() self.vehicles_N = vehicles_N self.vehicles_W = vehicles_W self.vehicles_E = vehicles_E self.sendData_1 = sendData_1 self.sendData_3 = sendData_3 self.my_result = 0 self.t_t = 0 self.initUI() self.timer = QTimer(self) self.timer.timeout.connect(self.update) self.timer.start(1000/60)#一秒間隔で更新 self.t = QTime() self.t.start() self.show() def initUI(self): self.setGeometry(300, 300, 600, 600) self.setWindowTitle("Koku's Simulation") self.ti = 0 self.beze_t = [] self.r = [] self.up_left_x = [] self.up_left_y = [] self.down_left_x = [] self.down_left_y = [] self.up_right_x = [] self.up_right_y = [] self.down_right_x = [] self.down_right_y = [] for i in range(10): self.beze_t.append(0) self.r.append(0) self.up_left_x.append(0) self.up_left_y.append(0) self.down_left_x.append(0) self.down_left_y.append(0) self.up_right_x.append(0) self.up_right_y.append(0) self.down_right_x.append(0) self.down_right_y.append(0) self.single_0_0 = True self.single_0_1 = True self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] self.grid = {} for i in range(270, 330, 10): for j in range(270, 330, 10): self.grid[(i, j)] = True def paintEvent(self, e): self.t_t += 1 qp = QPainter(self) self.drawLines(qp) #self.drawSignals_0(qp) self.drawVehicles(qp) def drawLines(self, qp): # print(self.t.elapsed()) pen = QPen(Qt.black, 2, Qt.SolidLine) pen_dash = QPen(Qt.black, 2, Qt.DotLine) # Vertical qp.setPen(pen) qp.drawLine(270, 0, 270, 600) # with grids ################## # qp.drawLine(280, 0, 280, 600) # qp.drawLine(290, 0, 290, 600) # qp.drawLine(300, 0, 300, 600) # qp.drawLine(310, 0, 310, 600) # qp.drawLine(320, 0, 320, 600) # with grids ################## qp.drawLine(330, 0, 330, 600) qp.drawLine(300, 0, 300, 270) qp.drawLine(300, 330, 300, 600) qp.setPen(pen_dash) qp.drawLine(280, 330, 280, 600) qp.drawLine(290, 330, 290, 600) qp.drawLine(310, 330, 310, 600) qp.drawLine(320, 330, 320, 600) qp.drawLine(280, 0, 280, 270) qp.drawLine(290, 0, 290, 270) qp.drawLine(310, 0, 310, 270) qp.drawLine(320, 0, 320, 270) # Tropical qp.setPen(pen) qp.drawLine(0, 270, 600, 270) # with grids ################## # qp.drawLine(0, 280, 600, 280) # qp.drawLine(0, 290, 600, 290) # qp.drawLine(0, 300, 600, 300) # qp.drawLine(0, 310, 600, 310) # qp.drawLine(0, 320, 600, 320) # with grids ################## qp.drawLine(0, 330, 600, 330) qp.drawLine(0, 300, 270, 300) qp.drawLine(330, 300, 600, 300) qp.setPen(pen_dash) qp.drawLine(0, 280, 270, 280) qp.drawLine(0, 290, 270, 290) qp.drawLine(0, 310, 270, 310) qp.drawLine(0, 320, 270, 320) qp.drawLine(330, 280, 600, 280) qp.drawLine(330, 290, 600, 290) qp.drawLine(330, 310, 600, 310) qp.drawLine(330, 320, 600, 320) def drawSignals_0(self, qp): #print(self.t.elapsed()) if 1000 < self.t.elapsed() < 2000: qp.setPen(Qt.black) qp.setBrush(Qt.red) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = False self.single_0_1 = True else: qp.setPen(Qt.black) qp.setBrush(Qt.green) qp.drawEllipse(272, 262, 6, 6) qp.drawEllipse(282, 262, 6, 6) qp.drawEllipse(292, 262, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(332, 272, 6, 6) qp.drawEllipse(332, 282, 6, 6) qp.drawEllipse(332, 292, 6, 6) qp.setBrush(Qt.green) qp.drawEllipse(302, 332, 6, 6) qp.drawEllipse(312, 332, 6, 6) qp.drawEllipse(322, 332, 6, 6) qp.setBrush(Qt.red) qp.drawEllipse(262, 302, 6, 6) qp.drawEllipse(262, 312, 6, 6) qp.drawEllipse(262, 322, 6, 6) self.single_0_0 = True self.single_0_1 = False def coordinate_up_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_up_left_y(self, po_y): return po_y def coordinate_up_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_up_right_y(self, po_y): return po_y def coordinate_down_left_x(self, po_x, r): return po_x - 5 * math.cos(math.radians(r)) def coordinate_down_left_y(self, po_y, r): return po_y + 5 * math.sin(math.radians(r)) + 10 * math.cos(math.radians(r)) def coordinate_down_right_x(self, po_x, r): return po_x + 10 * math.cos(math.radians(r)) def coordinate_down_right_y(self, po_y, r): return po_y + 10 * math.sin(math.radians(r)) + 5 * math.cos(math.radians(r)) def propose_pattern_1(self, veh_id, current, origin, destination, speed, current_time, pattern): server_address = ('localhost', 6789) max_size = 4096 print('Starting the client at', datetime.now()) client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sendData_1["pattern"] = 3 #self.sendData_1["position"] = list(current) current_position = list(current) print('++++++++++++++++++++++++++++++++++++++') print(self.sendData_1) self.sendData_1["origin"] = list(origin) self.sendData_1["destination"] = list(destination) self.sendData_1["speed"] = speed #self.sendData_1["current_time"] = current_time # sendData_1: veh info and current Total_time #mes = bytes(json.dumps(dict({"time_step": self.t_t}, **self.sendData_1["vehicle"][veh_id])), encoding='utf-8') dictMerge = dict({"time_step": self.t_t}, **self.sendData_1["vehicle"][veh_id]) dictMerge = dict({"position": current_position}, **dictMerge) mes = bytes(json.dumps(dictMerge), encoding='utf-8') #print(mes) client.sendto(mes, server_address) data, server = client.recvfrom(max_size) data = data.decode('utf-8') recData = json.loads(data) print('At', datetime.now(), server, 'said', recData) client.close() #print('!!!!!!!', recData['result']) self.my_result = recData['result'] return self.my_result def propose_pattern_3(self, veh_id, current, origin, destination, speed, current_time): server_address = ('localhost', 6789) max_size = 4096 print('Starting the client at', datetime.now()) client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.sendData_3["pattern"] = 3 self.sendData_3["position"] = list(current) self.sendData_3["origin"] = list(origin) self.sendData_3["destination"] = list(destination) self.sendData_3["speed"] = speed self.sendData_3["current_time"] = current_time # sendData_3: veh info and current Total_time mes = bytes(json.dumps(dict({"time_step": self.t_t}, **self.sendData_3["vehicle"][veh_id])), encoding='utf-8') print(mes) client.sendto(mes, server_address) data, server = client.recvfrom(max_size) data = data.decode('utf-8') recData = json.loads(data) print('At', datetime.now(), server, 'said', recData) client.close() #print('!!!!!!!', recData['result']) self.my_result = recData['result'] return self.my_result def drawVehicles(self, qp): qp.setPen(Qt.black) qp.setBrush(Qt.green) #qp.drawRect(310, 310, 5, 10) #self.propose(1, [262, 273], [270, 273], [330, 330], 2) # for i in range(10): # if self.propose(i): # print('?????????????') # qp.drawRect(322, 330, 5, 10) # else: # print('!!!!!!!!!!!!!') # qp.drawRect(400, 400, 5, 10) # Vehicles from North # for i, veh in enumerate(vehicles_N): # if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_N: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # else: # if veh.getPosition().y + veh.getSpeed().y > 260 and veh.getPosition().y <= 260: # if self.single_0_1: # qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # else: # if veh.getPosition().y <= 270: # if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: # # veh.getPosition().y += veh.getSpeed().y # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # self.grid[(veh.getPosition().x // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSize().x) // 10 * 10, (veh.getPosition().y + veh.getSize().y) // 10 * 10)] = False # else: # try: # if self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] and \ # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)]: # # self.vehicles_N[i].getPosition().y += veh.getSpeed().y # # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False # self.grid[((veh.getPosition().x + veh.getSpeed().x + veh.getSize().x) // 10 * 10, # (veh.getPosition().y + veh.getSpeed().y + veh.getSize().y) // 10 * 10)] = False # # if self.vehicles_N[i].getPosition().y > 600: # self.vehicles_N[i].getPosition().y = 0 # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) # # except KeyError: # self.vehicles_N[i].getPosition().y += veh.getSpeed().y # # if self.vehicles_N[i].getPosition().y > 600: # self.vehicles_N[i].getPosition().y = 0 # # qp.drawRect(self.vehicles_N[i].getPosition().x, self.vehicles_N[i].getPosition().y, 5, 10) # # else: # # print(self.single_0_1) # veh.getPosition().y += veh.getSpeed().y # if veh.getPosition().y > 600: # veh.getPosition().y = 0 # # print(self.t.elapsed()) # qp.drawRect(veh.getPosition().x, veh.getPosition().y, 5, 10) # for i in range(11): # self.collision_check_N.append((veh.getPosition().x, veh.getPosition().y - i)) #print(self.collision_check) # Vehicles from West for i, veh in enumerate(vehicles_W): # Check if there are vehicles ahead. If true, stop if (veh.getPosition().x + veh.getSpeed().x, veh.getPosition().y + veh.getSpeed().y) in self.collision_check_W: qp.drawRect(veh.getPosition().x, veh.getPosition().y, veh.getSize().x, veh.getSize().y) # Make the room not available for other vehicles for j in range(11): self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # Move forward else: # Just before the intersection if veh.getPosition().x + 10 + 2 > 270 and veh.getPosition().x <= 270 - 10: #+++++++++++++++++++++++++++++++++++++++++++++++++++++++ # Check traffic signal. True, then stop before entering. #print(veh.getPosition()) if not self.propose_pattern_1(i, (veh.getPosition().x, veh.getPosition().y), (270, 273), (330, 330), veh.getSpeed().x, self.t_t, 1): # if True: qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # Enter intersection else: veh.getPosition().x += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # # Light up the grids in the intersection # # Up left # if (veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: # self.grid[(veh.getPosition().x // 10 * 10, veh.getPosition().y // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Up right # if ((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10) in self.grid: # self.grid[((veh.getPosition().x + 10) // 10 * 10, veh.getPosition().y // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Down left # if (veh.getPosition().x // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: # self.grid[(veh.getPosition().x // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # # # Down right # if ((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y) // 10 * 10) in self.grid: # self.grid[((veh.getPosition().x + 10) // 10 * 10, (veh.getPosition().y + 5) // 10 * 10)] = False # #print('success, x:', veh.getPosition().x) # Already in the intersection else: if 270 < veh.getPosition().x < 328 and veh.getPosition().y < 330: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) # Calculate rotation angle if (((veh.getPosition().x - 270 + 3) / 60) * 90 > 15): self.r[i] = ((veh.getPosition().x - 270 + 3) / 60) * 90 qp.rotate(self.r[i]) else: self.r[i] = 0 qp.rotate(self.r[i]) qp.translate(-veh.getPosition().x, -veh.getPosition().y) # Calculate trajectory by using Bezier Curve x = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 332 + pow( self.beze_t[i] / 60, 2) * 332 y = pow(1 - (self.beze_t[i] / 60), 2) * 273 + 2 * (self.beze_t[i] / 60) * ( 1 - self.beze_t[i] / 60) * 273 + pow( self.beze_t[i] / 60, 2) * 332 veh.setPosition(Position(x, y)) self.beze_t[i] += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) qp.restore() # Calculate the big Square's coordinate self.up_left_x[i] = self.coordinate_up_left_x(veh.getPosition().x, self.r[i]) self.up_left_y[i] = self.coordinate_up_left_y(veh.getPosition().y) self.down_left_x[i] = self.coordinate_down_left_x(veh.getPosition().x, self.r[i]) self.down_left_y[i] = self.coordinate_down_left_y(veh.getPosition().y, self.r[i]) self.up_right_x[i] = self.coordinate_up_right_x(veh.getPosition().x, self.r[i]) self.up_right_y[i] = self.coordinate_up_right_y(veh.getPosition().y) self.down_right_x[i] = self.coordinate_down_right_x(veh.getPosition().x, self.r[i]) self.down_right_y[i] = self.coordinate_down_right_y(veh.getPosition().y, self.r[i]) # # Up left # if (self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10) in self.grid: # self.grid[(self.up_left_x[i] // 10 * 10, self.up_left_y[i] // 10 * 10)] = False # # print('success') # # # Up right # if ((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10) in self.grid: # self.grid[((self.up_right_x[i]) // 10 * 10, self.up_right_y[i] // 10 * 10)] = False # # print('success') # # # Down left # if (self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10) in self.grid: # self.grid[(self.down_left_x[i] // 10 * 10, (self.down_left_y[i]) // 10 * 10)] = False # # print('success') # # # Down right # if ((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10) in self.grid: # self.grid[((self.down_right_x[i]) // 10 * 10, (self.down_right_y[i]) // 10 * 10)] = False # # print('success') # Already left intersection elif 328 <= veh.getPosition().x and veh.getPosition().y < 600: qp.save() qp.translate(veh.getPosition().x, veh.getPosition().y) qp.rotate(90) qp.translate(-veh.getPosition().x, -veh.getPosition().y) veh.getPosition().y += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x, veh.getPosition().y - j)) qp.restore() # Already left screen elif veh.getPosition().y >= 600: veh.getPosition().x = 0 veh.getPosition().y = 273 self.beze_t[i] = 0 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x, veh.getPosition().y - j)) # Move horizontal direction(across X_axis) else: veh.getPosition().x += 2 qp.drawRect(veh.getPosition().x, veh.getPosition().y, 10, 5) for j in range(11): self.collision_check_W.append((veh.getPosition().x - j, veh.getPosition().y)) # Vehicle2 # if self.single_0_0: # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # else: if 330 <= (vehicles_E[0].getPosition().x) and (vehicles_E[0].getPosition().x - vehicles_E[0].getSpeed().x) < 330: #if self.propose_pattern_3(0, (veh.getPosition().x, veh.getPosition().y), (330, 272), (260, 272), veh.getSpeed().x, self.t_t): if True: self.vehicles_E[0].getPosition().x -= self.vehicles_E[0].getSpeed().x if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) else: qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) else: self.vehicles_E[0].getPosition().x -= self.vehicles_E[0].getSpeed().x if self.vehicles_E[0].getPosition().x < 0: self.vehicles_E[0].getPosition().x = 600 qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) ############################################################################################### # Just for seminar0920 # if 492 < self.t_t and self.t_t < 523: # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # else: # self.vehicles_E[0].getPosition().x -= self.vehicles_E[0].getSpeed().x # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # if self.vehicles_E[0].getPosition().x < 0: # self.vehicles_E[0].getPosition().x = 600 ############################################################################################### # try: # if self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, self.vehicles_E[0].getPosition().y // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)] and \ # self.grid[((self.vehicles_E[0].getPosition().x + 10 - 5) // 10 * 10, (self.vehicles_E[0].getPosition().y + 5) // 10 * 10)]: # # self.vehicles_E[0].getPosition().x -= 3 # # if self.vehicles_E[0].getPosition().x < 0: # self.vehicles_E[0].getPosition().x = 600 # # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # else: # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) # # except KeyError: # self.vehicles_E[0].getPosition().x -= 3 # # if self.vehicles_E[0].getPosition().x < 0: # self.vehicles_E[0].getPosition().x = 600 # # qp.drawPoint(self.vehicles_E[0].getPosition().x + 1, self.vehicles_E[0].getPosition().y - 1) # qp.drawRect(self.vehicles_E[0].getPosition().x, self.vehicles_E[0].getPosition().y, 10, 5) self.collision_check = [] self.collision_check_N = [] self.collision_check_S = [] self.collision_check_W = [] self.collision_check_E = [] # # # for i in range(270, 330, 10): # for j in range(270, 330, 10): # self.grid[(i, j)] = True # # self.ti += 10 if self.ti > 700: self.ti = 0 # print(self.t.elapsed()) self.t.restart()
class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.random_line = "" self.line_number = 0 self.time = QTime() self.time.start() # Create grid layout grid = QGridLayout() grid.setContentsMargins(1, 1, 1, 1) grid.setSpacing(1) self.setLayout(grid) # Create text input widget self.entry_widget = MyLineEdit() grid.addWidget(self.entry_widget, 0, 0, 1, 5, Qt.AlignTop) grid.setRowStretch(0, 0) # Create text display widget self.text_widget = QTextEdit(self) self.text_widget.setReadOnly(True) grid.addWidget(self.text_widget, 1, 0, 1, 5, Qt.AlignTop) grid.setRowStretch(1, 10) # Create information labels hbox = QHBoxLayout() grid.addLayout(hbox, 2, 0, 1, 5) # Current wpm label self.wpm_current_label = QLabel(self) self.wpm_current_label.setMaximumWidth(140) self.wpm_current_label.setTextFormat(Qt.RichText) hbox.addWidget(self.wpm_current_label) # Average wpm label self.wpm_average_label = QLabel(self) hbox.addWidget(self.wpm_average_label) # Number of errors label self.errors_label = QLabel(self) hbox.addWidget(self.errors_label) self.initialize_all() self.background_right = "background-color: white;" self.background_wrong = "background-color: pink;" self.font = "font-size: 12pt; font-family: Verdana;font-weight: bold;" self.next_char = """<p1 style="background-color:lightblue;">""" self.wpm_current_label.setStyleSheet(self.font) self.wpm_average_label.setStyleSheet(self.font) self.errors_label.setStyleSheet(self.font) self.entry_widget.setStyleSheet(self.background_right + self.font) self.text_widget.setStyleSheet("QTextEdit{{{} {}}}".format( self.background_right, self.font)) self.load_random_line() self.entry_widget.textChanged.connect( lambda changed: self.text_widget_handler(changed, self.random_line )) self.setGeometry(580, 0, 515, 115) self.setWindowTitle('Type Tester') self.show() def initialize_all(self, clear_text_widget=False): self.test_end = False self.test_start = False self.entry_widget.setReadOnly(False) self.match_end_index = 0 self.wpm_value = 0 self.error_counter = 0 self.time.restart() self.average_value = self.get_average_speed("speed_records.txt") self.wpm_current_label.setText("WMP : {:.2f}".format(self.wpm_value)) self.wpm_average_label.setText("Average : {:.2f}".format( self.average_value)) self.errors_label.setText("#Error : {:d}".format(self.error_counter)) if clear_text_widget: self.text_widget.setHtml(self.next_char + self.random_line[0] + "</p1>" + self.random_line[1:]) def keyReleaseEvent(self, event): if event.key() == Qt.Key_Tab: self.entry_widget.clear() self.entry_widget.setFocus() self.initialize_all(True) if event.key() == Qt.Key_Escape: self.entry_widget.clear() self.load_random_line() self.initialize_all() def get_random_line(self, filename): with open(filename, "rt", encoding="utf-8") as text_file: random_line = next(text_file) line_number = 0 for num, line in enumerate(text_file): if random.randrange(num + 2): continue random_line = line line_number = num return line_number, random_line def load_random_line(self): self.text_widget.clear() self.line_number, self.random_line = self.get_random_line( "english_conversations2.txt") self.text_widget.setHtml(self.next_char + self.random_line[0] + "</p1>" + self.random_line[1:]) def matcher(self, string_a, string_b): """ string_a : input string string_b : full string to match to return len(not_matched_chars, matched_chars) """ if string_a == string_b[0:len(string_a)]: matched = len(string_a) else: matched = self.match_end_index for i, char in enumerate(string_a[self.match_end_index + 1:len(string_a)]): if string_a[0:self.match_end_index + 1 + i] == string_b[0:self.match_end_index + 1 + i]: matched += 1 not_matched = len(string_a) - matched self.match_end_index = matched return not_matched, matched def text_widget_handler(self, string_a, string_b): if self.test_end: return None not_matched, matched = self.matcher(string_a, string_b) if not_matched >= 1: if not self.entry_widget.backspace_flag: self.error_counter += 1 self.errors_label.setText("#Error : {:d}".format( self.error_counter)) self.text_widget.setStyleSheet("QTextEdit{{{} {}}}".format( self.background_wrong, self.font)) self.text_widget.setHtml( "<font color=\"Gray\">" + string_b[:matched] + "</font>" + # self.next_char + # string_b[matched] + "</p1>" + "<font color=\"Red\">" + string_b[matched:matched + not_matched] + "</font>" + string_b[matched + not_matched:]) else: if (not self.test_start) and (matched > 0): self.time.restart() self.wpm_value = 0 self.test_start = True self.text_widget.setStyleSheet("QTextEdit{{{} {}}}".format( self.background_right, self.font)) self.text_widget.setHtml( "<font color=\"Gray\">" + string_b[:matched] + "</font>" + self.next_char + string_b[matched] + "</p1>" + # "<font color=\"Red\">" + # string_b[matched:matched+not_matched] + # "</font>" + string_b[matched + 1 + not_matched:]) # Calculation for wpm if self.test_start: if not self.time.elapsed(): self.wpm_value = 999 else: self.wpm_value = round( (matched) / (5 * (self.time.elapsed()) / (1000 * 60)), 2) if self.wpm_value > 999: self.wpm_value = 999 self.wpm_current_label.setText("WMP : {:.2f}".format(self.wpm_value)) if matched == (len(self.random_line) - 1): self.write_record("speed_records.txt", self.wpm_value) self.average_value = self.get_average_speed("speed_records.txt") self.wpm_average_label.setText("Average : {:.2f}".format( self.average_value)) self.test_end = True self.entry_widget.setReadOnly(True) def write_record(self, filename, wpm_value): with open(filename, "a") as record_file: record_file.write(str(wpm_value) + "\n") def get_average_speed(self, filename): average = 0 count = 0 with open(filename, "rt") as record_file: for value in record_file: average += float(value) count += 1 average = average / count return round(average, 2)