예제 #1
0
파일: main.py 프로젝트: emslGit/qtapp
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()
예제 #2
0
    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()
예제 #3
0
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()
예제 #4
0
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())
예제 #5
0
파일: main.py 프로젝트: aole/Chess-Coach
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)
예제 #6
0
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()
예제 #7
0
파일: bar.py 프로젝트: iggy/qutebrowser
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())
예제 #8
0
파일: qtdemo.py 프로젝트: Axel-Erfurt/pyqt5
def artisticSleep(sleepTime):
    time = QTime()
    time.restart()
    while time.elapsed() < sleepTime:
        QApplication.processEvents(QEventLoop.AllEvents, 50)
예제 #9
0
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'})
예제 #10
0
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()))
예제 #11
0
파일: bar.py 프로젝트: iggy/qutebrowser
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())
예제 #12
0
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()
예제 #13
0
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()
예제 #14
0
    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()
예제 #15
0
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
예제 #16
0
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)
예제 #17
0
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 = []
예제 #18
0
def artisticSleep(sleepTime):
    time = QTime()
    time.restart()
    while time.elapsed() < sleepTime:
        QApplication.processEvents(QEventLoop.AllEvents, 50)
예제 #19
0
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)
예제 #20
0
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()))
예제 #21
0
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)