Example #1
0
def createImage(window, settings, path):
    # Retrieve settings
    image = settings['path'] if 'path' in settings else ''
    geometry = settings['geometry'] if 'geometry' in settings else [
        0, 0, 50, 50, 7
    ]
    # Process alignment
    if len(geometry) == 4: geometry.append(7)
    geometry, _ = getPosFromGeometry(geometry)
    # Process image path
    path = path + '/Resources/' + image
    extension = path[(path.rfind('.') + 1):]
    # Create components
    elem = None
    if extension == 'svg':
        elem = QSvgWidget(path, window)
        elem.setGeometry(geometry[0], geometry[1], geometry[2], geometry[3])
        elem.show()
    else:
        elem = QLabel(window)
        elem.setGeometry(geometry[0], geometry[1], geometry[2], geometry[3])
        pixmap = QPixmap(path)
        elem.setPixmap(pixmap)
        elem.show()
    return elem
Example #2
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 1000, 1000)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 900, 900)

        self.chessboard = chess.Board()

    def play(self, ai_params):
        while not self.chessboard.is_game_over():
            self.widgetSvg.load(
                chess.svg.board(self.chessboard, flipped=True).encode("UTF-8"))
            if self.chessboard.turn:
                print("Whites turn")
                self.chessboard.push(findBestMove(ai_params, self.chessboard))
            else:
                print("Blacks turn")
                while True:
                    legal_moves = [
                        str(move) for move in list(self.chessboard.legal_moves)
                    ]
                    move = input("Your move: ")
                    if move in legal_moves:
                        self.chessboard.push(chess.Move.from_uci(move))
                        break
                    else:
                        print(move, "This is not a legal move!")
                        print("Legal moves are: ", legal_moves)
        self.widgetSvg.load(
            chess.svg.board(self.chessboard, flipped=True).encode("UTF-8"))
        print("Game Over")
Example #3
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 1100, 1100)
        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 1000, 1000)
Example #4
0
class MyWidget(QtWidgets.QWidget):
    def __init__(self):
        """
        This is the main window from my GUI
        """
        super().__init__()
        # Generate chess board
        self.setGeometry(0, 0, 620, 620)
        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 600, 600)
        self.chessboard = chess.Board()
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

        # configure and start thrread
        self.displayer_chess_game = ChessEngineBackend()
        self.thread = QtCore.QThread(self)
        self.displayer_chess_game.move.connect(self.move_callback)  # NOQA
        self.displayer_chess_game.moveToThread(self.thread)
        self.thread.started.connect(
            self.displayer_chess_game.chess_engine_backend)  # NOQA
        self.thread.start()

    @QtCore.pyqtSlot(str)
    def move_callback(self, move):
        """


        """
        self.chessboard.push(chess.Move.from_uci(move))
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
Example #5
0
class MainWindow(QWidget):
    def draw(self, mainlineMove):
        self.i += 1
        self.chessboard.push(mainlineMove)
        self.chessboardSvg = chess.svg.board(self.chessboard).encode('UTF-8')
        self.widgetSvg.load(self.chessboardSvg)

    def __init__(self, game):

        super().__init__()
        self.i = 0
        if game == None:
            self.chessboard = chess.Board()
        else:
            self.chessboard = game.board()
            self.MOVES = [x for x in game.mainline_moves()]
            print(self.MOVES)

        self.setGeometry(100, 100, 1000, 1000)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 960, 960)

        self.button = QPushButton("Next Move")
        self.button.clicked.connect(self.draw(self.MOVES[self.i]))

        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
Example #6
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.movehistory = []
        self.game = chess.pgn.Game()

        self.setGeometry(1050, 200, 500, 500)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(0, 0, 500, 500)

        self.boardSize = min(self.widgetSvg.width(), self.widgetSvg.height())
        self.squareSize = self.boardSize / 8.0
        self.pieceToMove = [None, None]

        self.board = chess.Board()

        self.drawBoard()

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        if self.board.is_game_over(claim_draw=True) is False:
            if not self.board.turn:
                move = select_move(self.board, DEPTH)
                self.board.push(move)
                self.movehistory.append(move)
            elif event.x() <= self.boardSize and event.y() <= self.boardSize:
                if event.buttons() == Qt.LeftButton:
                    file = int((event.x()) / self.squareSize)
                    rank = 7 - int((event.y()) / self.squareSize)
                    square = chess.square(file, rank)
                    piece = self.board.piece_at(square)
                    coordinates = "{}{}".format(chr(file + 97), str(rank + 1))
                    if self.pieceToMove[0] is not None:
                        move = chess.Move.from_uci("{}{}".format(
                            self.pieceToMove[1], coordinates))
                        if move in self.board.legal_moves:
                            self.board.push(move)
                            self.movehistory.append(move)
                        piece = None
                        coordinates = None
                    self.pieceToMove = [piece, coordinates]
            self.drawBoard()
        else:
            self.game.add_line(self.movehistory)
            print(self.game, file=open("gameresult.pgn", "w"), end="\n\n")
            print("Game over")
            exit()

    def drawBoard(self):
        lastmove = self.board.peek() if self.board.move_stack else None
        self.boardSvg = chess.svg.board(board=self.board,
                                        lastmove=lastmove).encode("UTF-8")
        self.drawBoardSvg = self.widgetSvg.load(self.boardSvg)

        return self.boardSvg
Example #7
0
class MainWindow(QWidget):
    def __init__(self, board):
        super().__init__()

        self.setGeometry(100, 100, 520, 520)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 500, 500)

        self.set_board(board)

    def set_board(self, board):
        chessboardSvg = chess.svg.board(board).encode("UTF-8")
        self.widgetSvg.load(chessboardSvg)
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 1100, 1100)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 1080, 1080)

        self.chessboard = chess.Board()

        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

    def paintEvent(self, event):
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
Example #9
0
def init_board_window():
    def reload_svg():

        svg_bytes = bytearray(board_picture, encoding='utf-8')
        svgWidget.renderer().load(svg_bytes)
        svgWidget.update()

    svg_bytes = bytearray(board_picture, encoding='utf-8')
    app = QApplication(sys.argv)
    svgWidget = QSvgWidget()
    svgWidget.renderer().load(svg_bytes)
    svgWidget.setGeometry(200, 5, 440, 440)
    svgWidget.show()
    timer = QtCore.QTimer()
    timer.timeout.connect(lambda: reload_svg())
    timer.start(500)
    sys.exit(app.exec_())
Example #10
0
class ScrollWindow(QScrollArea):
    def __init__(self, *args, **kwargs):
        super(ScrollWindow, self).__init__(*args, **kwargs)
        # self.setAcceptDrops(True)  # 2
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)
        self.setWidgetResizable(True)
        self.setAlignment(Qt.AlignCenter)
        self._loadStart = False
        # 网格窗口
        self._widget = GridWidget(self)
        self._widget.loadStarted.connect(self.setLoadStarted)
        self.setWidget(self._widget)
        ####################################################
        # 连接竖着的滚动条滚动事件
        # self.verticalScrollBar().actionTriggered.connect(self.onActionTriggered)
        ####################################################
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=180,
                                     minimumWidth=180,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

    def setLoadStarted(self, started):
        self._loadStart = started
        self.loadWidget.setVisible(started)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self._widget.load()

    def resizeEvent(self, event):
        super(ScrollWindow, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())
Example #11
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 850, 850)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 800, 800)

        self.board = chess.Board()  #'8/8/8/rnbqk3/ppppp3/8/PPPPP3/RNBQK3')

        self.boardSvg = chess.svg.board(self.board).encode("UTF-8")
        self.widgetSvg.load(self.boardSvg)

    def reload(self):
        self.boardSvg = chess.svg.board(self.board).encode("UTF-8")
        self.widgetSvg.load(self.boardSvg)

    def replaceBoard(self, board):
        self.board = board
Example #12
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PinkFish")
        self.setGeometry(400, 400, 1300, 1300)
        self.widgetSvg = QSvgWidget(self)
        self.widgetSvg.setGeometry(20, 20, 1200, 1200)
        self.chessboard = chess.Board()
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")

        self.checkThreadTimer = QTimer(self)
        self.checkThreadTimer.setInterval(1000)
        self.checkThreadTimer.start()
        self.checkThreadTimer.timeout.connect(self.play)

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.update()

    @pyqtSlot(QWidget)
    def paintEvent(self, event):
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

    def play(self):
        dirname = os.path.dirname(__file__)
        filename = os.path.join(dirname, 'stockfish-9-win\Windows\stockfish_9_x64')
        stockfish = Stockfish(filename)
        stockfish.set_skill_level(15)
        if not self.chessboard.is_game_over() and not self.chessboard.is_stalemate():
            board = self.chessboard.fen()
            stockfish.set_fen_position(board)
            ai_move = stockfish.get_best_move()
            move = chess.Move.from_uci(ai_move)
            print(move)
            self.chessboard.push(move)
            self.update()
Example #13
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 500, 500)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 480, 480)

        self.chessboard = chess.Board()

        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

    def paintEvent(self, event):
        self.game_over()
        self.rand()
        self.tela_jog()

    def tela_jog(self):
        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)

    def game_over(self):
        if self.chessboard.is_game_over() == True:
            print(self.chessboard.outcome())
            input()
            exit()

    def rand(self):
        legal_count = self.chessboard.legal_moves.count()
        move_list = list(self.chessboard.legal_moves)  # Find legal moves
        which_move = random.randint(0, legal_count - 1)  # Random move index
        first_move = move_list[which_move]  # Select move
        move_holder = chess.Move.from_uci(str(first_move))

        self.chessboard.push(move_holder)
        time.sleep(0.5)
Example #14
0
class Window(QWidget):
    def __init__(self, left=100, top=100, width=500, height=500):
        super().__init__()
        self.left = max(0, left)
        self.top = max(0, top)
        self.width = max(20, width)
        self.height = max(20, height)
        self.update_geometry()
        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, self.width - 20, self.height - 20)

    def update_geometry(self):
        self.setGeometry(self.left, self.top, self.width, self.height)

    def display_svg(self, svg):
        self.widgetSvg.load(svg)
        self.repaint()

    def add_button(self, text, on_click):
        btn = QPushButton(text, self)
        self.height = self.height + 60
        self.update_geometry()
        btn.move(int(self.width / 2) - 50, self.height - 50)
        btn.clicked.connect(on_click)
Example #15
0
class MainWindow(QWidget):
    """
    Create a surface for the chessboard.
    """
    def __init__(self):
        """
        Initialize the chessboard.
        """
        super().__init__()

        self.setWindowTitle("DeepChess")
        self.setGeometry(300, 300, 800, 800)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 600, 600)

        self.label = QLabel('---', parent=self)
        self.label.setGeometry(10, 600, 600, 100)

        self.boardSize = min(self.widgetSvg.width(), self.widgetSvg.height())
        self.coordinates = True
        self.margin = 0.05 * self.boardSize if self.coordinates else 0
        self.squareSize = (self.boardSize - 2 * self.margin) / 8.0
        self.playerMove = True

        self.engine = DeepChess('b')
        #self.board = chess.Board()
        self.pieceToMove = [None, None]
        self.updateBoard()

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        """
        Handle left mouse clicks and enable moving chess pieces by
        clicking on a chess piece and then the target square.

        Moves must be made according to the rules of chess because
        illegal moves are suppressed.
        """
        if self.playerMove and event.x() <= self.boardSize and event.y(
        ) <= self.boardSize:
            if event.buttons() == Qt.LeftButton:
                if self.margin < event.x(
                ) < self.boardSize - self.margin and self.margin < event.y(
                ) < self.boardSize - self.margin:
                    file = int((event.x() - self.margin) / self.squareSize)
                    rank = 7 - int((event.y() - self.margin) / self.squareSize)
                    square = chess.square(file, rank)
                    piece = self.engine.board.piece_at(square)
                    coordinates = "{}{}".format(chr(file + 97), str(rank + 1))
                    if self.pieceToMove[0] is not None and self.pieceToMove[
                            1] != coordinates:
                        move = chess.Move.from_uci("{}{}".format(
                            self.pieceToMove[1], coordinates))
                        if move in self.engine.board.legal_moves:
                            self.engine.board.push(move)
                            if self.engine.board.is_check():
                                self.label.setText("Check!")
                            self.playerMove = False
                            # start timer
                            self.label.setText('DeepChess evaluating move...')
                            QTimer.singleShot(200, self.deepchess_evaluate)
                        piece = None
                        coordinates = None
                    self.pieceToMove = [piece, coordinates]
                    self.updateBoard()
                else:
                    # Envoke the paint event.
                    #self.update()
                    self.updateBoard()
        else:
            QWidget.mousePressEvent(self, event)

    #@pyqtSlot(QWidget)
    #def paintEvent(self, event):
    def updateBoard(self):
        """
        Draw a chessboard with the starting position and then redraw
        it for every new move.
        """
        self.boardSvg = chess.svg.board(board=self.engine.board,
                                        size=self.boardSize).encode("UTF-8")
        self.widgetSvg.load(self.boardSvg)
        if self.playerMove:
            self.label.setText('player move: {}-{}'.format(
                self.pieceToMove[0], self.pieceToMove[1]))

    def deepchess_evaluate(self):
        self.engine.evaluate()
        self.playerMove = True
        self.updateBoard()
Example #16
0
class ChessWindow(QMainWindow):
    def __init__(self, windowsize):
        super().__init__()
        self.windowsize = windowsize
        self.figure_size = int(board_dimension/8)
        self.chessboard = QSvgWidget('images/Chess_Board.svg')
        self.text = QLabel()
        self.pc_enemy_text = QLabel()
        self.win_text = QLabel()
        self.figures = [[0]*8 for i in range(8)]
        self.initUI()
        self.timer = QTimer()
        self.timer.timeout.connect(self.recursive_enemy)
        self.timer.start(1000)

    def initUI(self):
        self.setFixedSize(self.windowsize)
        self.setWindowFlags(Qt.CustomizeWindowHint | Qt.FramelessWindowHint)

        widget = QWidget()
        self.setCentralWidget(widget)

        if current_player == 1:
            self.text.setText('Current player: White')
        else:
            self.text.setText('Current player: Red')


        self.text.setFont(QFont('SansSerif', 25))
        self.text.setGeometry(QRect(board_dimension + offset_x + 50, offset_y, 500, 100))
        self.text.setParent(widget)

        self.win_text.setFont(QFont('SansSerif', 25))
        self.win_text.setGeometry(QRect(board_dimension + offset_x + 50, offset_y + 100, 500, 100))
        self.win_text.setParent(widget)

        if recursive_enemy:
            self.pc_enemy_text.setText('PC Enemy: ON')
            self.pc_enemy_text.setFont(QFont('SansSerif', 25))
            self.pc_enemy_text.setGeometry(QRect(board_dimension + offset_x + 50, offset_y + 50, 500, 100))

        self.pc_enemy_text.setParent(widget)

        self.chessboard.setGeometry(offset_x, offset_y, board_dimension, board_dimension)
        self.chessboard.setParent(widget)

        for x in range(0, 8):
            for y in range(0, 8):
                red_color = QGraphicsColorizeEffect()
                red_color.setColor(QColor(255, 0, 0))
                found = False
                # pawns
                if abs(Game.get_board()[x][y]) == 1:
                    new_figure = DragFigure('images/Chess_plt45.svg')
                    found = True
                # towers
                elif abs(Game.get_board()[x][y]) == 2:
                    new_figure = DragFigure('images/Chess_rlt45.svg')
                    found = True
                # rooks
                elif abs(Game.get_board()[x][y]) == 3:
                    new_figure = DragFigure('images/Chess_nlt45.svg')
                    found = True
                # bishops
                elif abs(Game.get_board()[x][y]) == 4:
                    new_figure = DragFigure('images/Chess_blt45.svg')
                    found = True
                # kings
                elif abs(Game.get_board()[x][y]) == 5:
                    new_figure = DragFigure('images/Chess_klt45.svg')
                    found = True
                # queens
                elif abs(Game.get_board()[x][y]) == 6:
                    new_figure = DragFigure('images/Chess_qlt45.svg')
                    found = True

                if found:
                    if Game.get_board()[x][y] < 0:
                        new_figure.setGraphicsEffect(red_color)
                    self.figures[x][y] = new_figure
                    new_figure.setGeometry(x * self.figure_size + offset_x, y * self.figure_size + offset_y, self.figure_size, self.figure_size)
                    new_figure.setParent(widget)

    def recursive_enemy(self):
        if current_player == -1:
            if recursive_enemy:
                print('Enemy turn')
                if not Game.finished(Game.get_board(), current_player):
                    print('Evaluating best move')
                    best_move = recursive_evaluation(Game.get_board(), current_player, current_player)
                    print('Best move found')
                    print(best_move)
                    self.move_figure(best_move)
                else:
                    reward_ai = Game.reward(Game.get_board(), current_player)
                    reward_human = Game.reward(Game.get_board(), -current_player)
                    self.pc_enemy_text.setText('Game finished!')
                    if reward_ai == 0 and reward_human == 0:
                        self.win_text.setText('Winner: Draw')
                    elif reward_ai == -1:
                        self.win_text.setText('Gratulation, Sieg!')
                    else:
                        self.win_text.setText('Schade, verloren.')
                    print('Game finished!')
            elif random_enemy:
                if not Game.finished(Game.get_board(), current_player):
                    print('Random move search')
                    move = random_move(Game.get_board(), current_player, current_player)
                    print('Random move found')
                    print(move)
                    self.move_figure(move)
                else:
                    reward_ai = Game.reward(Game.get_board(), current_player)
                    reward_human = Game.reward(Game.get_board(), -current_player)
                    self.pc_enemy_text.setText('Game finished!')
                    if reward_ai == 0 and reward_human == 0:
                        self.win_text.setText('Winner: Draw')
                    elif reward_ai == -1:
                        self.win_text.setText('Winner: Human')
                    else:
                        self.win_text.setText('Winner: AI')
                    self.pc_enemy_text.setText('Game finished!')


    def move_figure(self, move):
        global current_player
        global Game

        if -1 < move.x < 8 and -1 < move.y < 8 and -1 < move.x_new < 8 and -1 < move.y_new < 8:
            valid_moves = Game.get_valid_actions(Game.get_board(), current_player)

            new_board = deepcopy(Game.get_board())
            pawn_to_queen = False
            if current_player == 1 and move.y_new == 7 and new_board[move.x][move.y] == 1:
                new_board[move.x_new][move.y_new] = 6
                pawn_to_queen = True
            elif current_player == -1 and move.y_new == 0 and new_board[move.x][move.y] == -1:
                new_board[move.x_new][move.y_new] = -6
                pawn_to_queen = True
            else:
                new_board[move.x_new][move.y_new] = new_board[move.x][move.y]
            new_board[move.x][move.y] = 0

            valid_move = False
            for action in valid_moves:
                if action == new_board:
                    print('Valid Move!')
                    valid_move = True

            if valid_move:
                goal_value = Game.get_board()[move.x_new][move.y_new]
                goal_position = QPoint(move.x_new * self.figure_size + offset_x, move.y_new * self.figure_size + offset_y)
                if np.sign(goal_value) != current_player and goal_value != 0:
                    self.figures[move.x_new][move.y_new].move(-10000, -1000)
                    #self.parent().childAt(goal_position).move(-10000, -1000)

                move.execute_move()

                if pawn_to_queen:
                    self.figures[move.x][move.y].load('images/Chess_qlt45.svg')

                self.figures[move.x][move.y].setGeometry(goal_position.x(), goal_position.y(), self.figure_size, self.figure_size)

                self.figures[move.x_new][move.y_new] = self.figures[move.x][move.y]
                self.figures[move.x][move.y] = 0

                if current_player == 1:
                    self.centralWidget().childAt(QPoint(board_dimension + offset_x + 50, offset_y)).setText('Current player: White')
                else:
                    self.centralWidget().childAt(QPoint(board_dimension + offset_x + 50, offset_y)).setText('Current player: Red')
        else:
            print('Invalid move!')
Example #17
0
class ChessBoard(QWidget, chess.Board):
    """
      BRIEF  An interactive chessboard that only allows legal moves
   """

    ReadyForNextMove = pyqtSignal(str)
    GameOver = pyqtSignal()

    def __init__(self, parent=None):
        """
         BRIEF  Initialize the chessboard
      """
        super().__init__(parent)
        self.setWindowTitle("Chess")

        self.svg_xy = 50  # top left x,y-pos of chessboard
        self.board_size = 600  # size of chessboard
        self.margin = 0.05 * self.board_size
        self.square_size = (self.board_size - 2 * self.margin) / 8.0
        wnd_wh = self.board_size + 2 * self.svg_xy

        self.setMinimumSize(wnd_wh, wnd_wh)
        self.svg_widget = QSvgWidget(parent=self)
        self.svg_widget.setGeometry(self.svg_xy, self.svg_xy, self.board_size,
                                    self.board_size)

        self.last_click = None
        self.DrawBoard()

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        """
         BRIEF  Update the board state based on user clicks
                If the state changes, update the svg widget
      """
        if self.LeftClickedBoard(event):
            this_click = self.GetClicked(event)

            if self.last_click:
                if self.last_click != this_click:
                    uci = self.last_click + this_click
                    self.ApplyMove(uci + self.GetPromotion(uci))

            self.last_click = this_click

    def GetPromotion(self, uci):
        """
         BRIEF  Get the uci piece type the pawn will be promoted to
      """
        if chess.Move.from_uci(uci + 'q') in self.legal_moves:
            dialog = PromotionDialog(self)
            if dialog.exec() == QDialog.Accepted:
                return dialog.SelectedPiece()
        return ''

    @pyqtSlot(str)
    def ApplyMove(self, uci):
        """
         BRIEF  Apply a move to the board
      """
        move = chess.Move.from_uci(uci)
        if move in self.legal_moves:
            self.push(move)
            self.DrawBoard()

            print(self.fen())
            if not self.is_game_over():
                self.ReadyForNextMove.emit(self.fen())
            else:
                print("Game over!")
                self.GameOver.emit()
            sys.stdout.flush()

    @pyqtSlot()
    def UndoMove(self):
        """
      """
        try:
            self.pop()
            self.DrawBoard()
            self.ReadyForNextMove.emit(self.fen())
        except IndexError:
            pass

    def DrawBoard(self):
        """
         BRIEF  Redraw the chessboard based on board state
                Highlight src and dest squares for last move
                Highlight king if in check
      """
        self.svg_widget.load(self._repr_svg_().encode("utf-8"))

    def GetClicked(self, event):
        """
         BRIEF  Get the algebraic notation for the clicked square
      """
        top_left = self.svg_xy + self.margin
        file_i = int((event.x() - top_left) / self.square_size)
        rank_i = 7 - int((event.y() - top_left) / self.square_size)
        return chr(file_i + 97) + str(rank_i + 1)

    def LeftClickedBoard(self, event):
        """
         BRIEF  Check to see if they left-clicked on the chess board
      """
        topleft = self.svg_xy + self.margin
        bottomright = self.board_size + self.svg_xy - self.margin
        return all([
            event.buttons() == Qt.LeftButton,
            topleft < event.x() < bottomright,
            topleft < event.y() < bottomright,
        ])
Example #18
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Chess Titan")
        self.setGeometry(300, 300, 800, 800)

        self.widgetSvg = QSvgWidget(parent=self)
        self.svgX = 50  # top left x-pos of chessboard
        self.svgY = 50  # top left y-pos of chessboard
        self.cbSize = 600  # size of chessboard
        self.widgetSvg.setGeometry(self.svgX, self.svgY, self.cbSize,
                                   self.cbSize)
        self.coordinates = True
        # see chess.svg.py line 129
        self.margin = 0.05 * self.cbSize if self.coordinates == True else 0
        self.squareSize = (self.cbSize - 2 * self.margin) / 8.0
        self.chessboard = chess.Board("7K/8/8/8/8/8/8/8 ")
        self.pieceToMove = [None, None]

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        if self.svgX < event.x(
        ) <= self.svgX + self.cbSize and self.svgY < event.y(
        ) <= self.svgY + self.cbSize:  # mouse on chessboard
            print(self.svgX)
            print("//////")
            print(event.x())
            if event.buttons() == Qt.LeftButton:
                # if the click is on chessBoard only
                if self.svgX + self.margin < event.x(
                ) < self.svgX + self.cbSize - self.margin and self.svgY + self.margin < event.y(
                ) < self.svgY + self.cbSize - self.margin:
                    file = int((event.x() - (self.svgX + self.margin)) /
                               self.squareSize)
                    rank = 7 - int(
                        (event.y() -
                         (self.svgY + self.margin)) / self.squareSize)
                    square = chess.square(
                        file, rank)  # chess.sqare.mirror() if white is on top
                    piece = self.chessboard.piece_at(square)
                    coordinates = '{}{}'.format(chr(file + 97), str(rank + 1))
                    if self.pieceToMove[0] is not None:
                        move = chess.Move.from_uci('{}{}'.format(
                            self.pieceToMove[1], coordinates))
                        self.chessboard.push(move)
                        print(self.chessboard.fen())
                        piece = None
                        coordinates = None
                    self.pieceToMove = [piece, coordinates]
                else:
                    print('coordinates clicked')
                # Envoke the paint event.
                self.update()
        else:
            QWidget.mousePressEvent(self, event)

    @pyqtSlot(QWidget)
    def paintEvent(self, event):
        self.chessboardSvg = chess.svg.board(
            self.chessboard, size=self.cbSize,
            coordinates=self.coordinates).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
Example #19
0
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtSvg import QSvgWidget

svg_str = """<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="498" height="497"
        viewBox="-0.5 0 498 497" enable-background="new -0.5 0 498 497" xml:space="preserve">
<circle fill="#FFFF00" stroke="#000000" stroke-width="15" cx="248.5" cy="248.5" r="241"/>
<ellipse cx="144.166" cy="180.166" rx="44" ry="53.833"/>
<ellipse cx="337.666" cy="180.166" rx="44" ry="53.833"/>
<path d="M425.834,298c-14.334,20.5-78.127,131.167-174.5,131.167c-96.374,0-145.833-81.667-174.5-131.167
        c53.167,18.5,92.583,35.667,174.5,35.667C333.251,333.667,398.5,306.5,425.834,298z"/>
</svg> 
"""
# ==========================================
with open('smile.svg', 'w') as f:
    f.write(svg_str)
# ==========================================
app = QApplication(sys.argv)
svgWidget = QSvgWidget('smile.svg')
svgWidget.setGeometry(100,100,800,800)
svgWidget.show()
sys.exit(app.exec_())
Example #20
0
class Window(QListWidget):
    Page = 0

    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(800, 600)
        self.setFrameShape(self.NoFrame)  # 无边框
        self.setFlow(self.LeftToRight)  # 从左到右
        self.setWrapping(True)  # 这三个组合可以达到和FlowLayout一样的效果
        self.setResizeMode(self.Adjust)

        self._loadStart = False
        # 连接竖着的滚动条滚动事件
        self.verticalScrollBar().actionTriggered.connect(
            self.onActionTriggered)
        # 进度条
        self.loadWidget = QSvgWidget(self,
                                     minimumHeight=120,
                                     minimumWidth=120,
                                     visible=False)
        self.loadWidget.load(Svg_icon_loading)

        # 异步网络下载管理器
        self._manager = QNetworkAccessManager(self)
        self._manager.finished.connect(self.onFinished)

    def load(self):
        if self.Page == -1:
            return
        self._loadStart = True
        self.loadWidget.setVisible(True)
        # 延迟一秒后调用目的在于显示进度条
        QTimer.singleShot(1000, self._load)

    def _load(self):
        print("load url:", Url.format(self.Page * 30))
        url = QUrl(Url.format(self.Page * 30))
        self._manager.get(QNetworkRequest(url))

    def onFinished(self, reply):
        # 请求完成后会调用该函数
        req = reply.request()  # 获取请求
        iwidget = req.attribute(QNetworkRequest.User + 1, None)
        path = req.attribute(QNetworkRequest.User + 2, None)
        html = reply.readAll().data()
        reply.deleteLater()
        del reply
        if iwidget and path and html:
            # 这里是图片下载完毕
            open(path, "wb").write(html)
            iwidget.setCover(path)
            return
        # 解析网页
        self._parseHtml(html)
        self._loadStart = False
        self.loadWidget.setVisible(False)

    def _parseHtml(self, html):
        #         encoding = chardet.detect(html) or {}
        #         html = html.decode(encoding.get("encoding","utf-8"))
        html = HTML(html)
        # 查找所有的li list_item
        lis = html.xpath("//li[@class='list_item']")
        if not lis:
            self.Page = -1  # 后面没有页面了
            return
        self.Page += 1
        self._makeItem(lis)

    def _makeItem(self, lis):
        for li in lis:
            a = li.find("a")
            video_url = a.get("href")  # 视频播放地址
            img = a.find("img")
            cover_url = "http:" + img.get("r-lazyload")  # 封面图片
            figure_title = img.get("alt")  # 电影名
            figure_info = a.find("div/span")
            figure_info = "" if figure_info is None else figure_info.text  # 影片信息
            figure_score = "".join(li.xpath(".//em/text()"))  # 评分
            # 主演
            figure_desc = "<span style=\"font-size: 12px;\">主演:</span>" + \
                          "".join([Actor.format(**dict(fd.items()))
                                   for fd in li.xpath(".//div[@class='figure_desc']/a")])
            # 播放数
            figure_count = (
                li.xpath(".//div[@class='figure_count']/span/text()")
                or [""])[0]
            path = "cache/{0}.jpg".format(
                os.path.splitext(os.path.basename(video_url))[0])
            cover_path = "Data/pic_v.png"
            if os.path.isfile(path):
                cover_path = path
            iwidget = ItemWidget(cover_path, figure_info, figure_title,
                                 figure_score, figure_desc, figure_count,
                                 video_url, cover_url, path, self._manager,
                                 self)
            item = QListWidgetItem(self)
            item.setSizeHint(iwidget.sizeHint())
            self.setItemWidget(item, iwidget)

    def onActionTriggered(self, action):
        # 这里要判断action=QAbstractSlider.SliderMove,可以避免窗口大小改变的问题
        # 同时防止多次加载同一个url
        if action != QAbstractSlider.SliderMove or self._loadStart:
            return
        # 使用sliderPosition获取值可以同时满足鼠标滑动和拖动判断
        if self.verticalScrollBar().sliderPosition() == self.verticalScrollBar(
        ).maximum():
            # 可以下一页了
            self.load()

    def resizeEvent(self, event):
        super(Window, self).resizeEvent(event)
        self.loadWidget.setGeometry(
            int((self.width() - self.loadWidget.minimumWidth()) / 2),
            int((self.height() - self.loadWidget.minimumHeight()) / 2),
            self.loadWidget.minimumWidth(), self.loadWidget.minimumHeight())
Example #21
0
class MainWindow(QWidget):
    """
    Create a surface for the chessboard.
    """
    def __init__(self):
        """
        Initialize the chessboard.
        """
        super().__init__()

        self.setWindowTitle("Chess GUI")
        self.setGeometry(300, 300, 800, 800)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 600, 600)

        self.boardSize = min(self.widgetSvg.width(),
                             self.widgetSvg.height())
        self.coordinates = True
        self.margin = 0.05 * self.boardSize if self.coordinates else 0
        self.squareSize = (self.boardSize - 2 * self.margin) / 8.0
        self.pieceToMove = [None, None]

        self.board = chess.Board()
        self.drawBoard()

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        """
        Handle left mouse clicks and enable moving chess pieces by
        clicking on a chess piece and then the target square.

        Moves must be made according to the rules of chess because
        illegal moves are suppressed.
        """
        if event.x() <= self.boardSize and event.y() <= self.boardSize:
            if event.buttons() == Qt.LeftButton:
                if self.margin < event.x() < self.boardSize - self.margin and self.margin < event.y() < self.boardSize - self.margin:
                    file = int((event.x() - self.margin) / self.squareSize)
                    rank = 7 - int((event.y() - self.margin) / self.squareSize)
                    square = chess.square(file, rank) 
                    piece = self.board.piece_at(square)
                    coordinates = "{}{}".format(chr(file + 97), str(rank + 1))
                    if self.pieceToMove[0] is not None:
                        move = chess.Move.from_uci("{}{}".format(self.pieceToMove[1], coordinates))
                        if move in self.board.legal_moves:
                            self.board.push(move)
                            self.setWindowTitle("Ai making move")
                            time1=time.time()
                            from aiPlayer import AiPlayer
                            a = AiPlayer()
                            a.minimax(self.board)
                            time2=time.time()
                            print('Ai move took {:.3f} seconds'.format(time2-time1))
                            self.setWindowTitle("Chess GUI")
                        piece = None
                        coordinates = None
                    self.pieceToMove = [piece, coordinates]
                    self.drawBoard()

    def drawBoard(self):
        """
        Draw a chessboard with the starting position and then redraw
        it for every new move.
        """
        self.boardSvg = self.board._repr_svg_().encode("UTF-8")
        self.drawBoardSvg = self.widgetSvg.load(self.boardSvg)

        return self.drawBoardSvg
Example #22
0
class Window(QWidget):
    def __init__(self):
        super().__init__()

        model = keras.models.load_model("final/BuzdyganDQNv0_210k_target.h5f",
                                        compile=False)
        self.ai_engine = DQNChessEngine(model)
        self.board: chess.Board = chess.Board()
        self.chosen_piece = [None, None]
        self.last_ai_move: chess.Move = None
        self.result = None
        self.svg_clickable: bool = True

        # Geometry
        self.board_size = 600
        self.coordinates = True
        self.margin = .05 * self.board_size if self.coordinates else 0
        self.sqr_size = (self.board_size - 2 * self.margin) / 8.

        self.button_width = 100
        self.button_height = 50

        self.window_width = self.board_size + self.margin + self.button_width + 20
        self.window_height = self.board_size + self.margin

        self.svgX = 10
        self.svgY = 10

        self.setWindowTitle("DQNChess GUI")
        self.setFixedSize(self.window_width, self.window_height)

        self.board_svg = None
        self.svg_widget = QSvgWidget(parent=self)
        self.svg_widget.setGeometry(
            self.svgX,
            self.svgY,
            self.board_size,
            self.board_size,
        )

        self.restart_button = QPushButton("Play next round", self)
        self.restart_button.setGeometry(self.board_size + self.margin + 5,
                                        self.margin, self.button_width,
                                        self.button_height)
        self.restart_button.clicked.connect(self.restart)

        self.text_label = QLabel("Start playing.", self)
        self.text_label.setGeometry(self.board_size + self.margin + 5,
                                    self.margin * 2 + self.button_height, 100,
                                    20)

    def restart(self):
        self.board.reset()
        self.last_ai_move = None
        self.svg_clickable = True
        self.text_label.setText("Start playing.")

    def _is_game_over(self):
        if self.board.is_game_over():
            self.result = self.board.result()
            self.svg_clickable = False
            return True
        else:
            return False

    def _can_next_player_move(self):
        return not self._is_game_over()

    @staticmethod
    def _flip_move(move: chess.Move):
        uci = move.uci()
        from_column = uci[0]
        from_row = 9 - int(uci[1])
        to_column = uci[2]
        to_row = 9 - int(uci[3])
        flipped_move = chess.Move.from_uci("{}{}{}{}".format(
            from_column, from_row, to_column, to_row))
        return flipped_move

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event: QtGui.QMouseEvent):
        if self.svgX < event.x() <= self.svgX + self.board_size and \
                self.svgY < event.y() <= self.svgY + self.board_size:
            if event.buttons() == Qt.LeftButton:
                if self.svgX + self.margin < event.x() < self.svgX + self.board_size - self.margin and \
                        self.svgY + self.margin < event.y() < self.svgY + self.board_size - self.margin and \
                        self.svg_clickable:
                    file = int((event.x() - (self.svgX + self.margin)) /
                               self.sqr_size)
                    rank = 7 - int((event.y() -
                                    (self.svgY + self.margin)) / self.sqr_size)
                    square = chess.square(file, rank)
                    piece = self.board.piece_at(square)
                    coordinates = '{}{}'.format(chr(file + 97), str(rank + 1))
                    if self.chosen_piece[0] is not None:
                        move = chess.Move.from_uci('{}{}'.format(
                            self.chosen_piece[1], coordinates))
                        if move in self.board.legal_moves:
                            self.board.push(move)
                            piece = None
                            coordinates = None
                            can_ai_move = self._can_next_player_move()
                            if can_ai_move:
                                cb_board = ChessBoard(self.board.fen())
                                ai_move, _ = self.ai_engine.choose_move(
                                    cb_board, flip=True)
                                ai_move = self._flip_move(ai_move)
                                self.board.push(ai_move)
                                self.last_ai_move = ai_move
                                self._can_next_player_move()
                    self.chosen_piece = [piece, coordinates]
            self.update()
        else:
            QWidget.mousePressEvent(self, event)

    @pyqtSlot(QWidget)
    def paintEvent(self, a0: QtGui.QPaintEvent):
        king_attacked_by = None
        if self._is_game_over():
            if self.result == '1-0':
                king_square = self.board.king(False)
                king_attacked_by = self.board.attackers(True, king_square)
                self.text_label.setText("You have won!")
            elif self.result == '0-1':
                king_square = self.board.king(True)
                king_attacked_by = self.board.attackers(False, king_square)
                self.text_label.setText("You have lost! :(")
            else:
                self.text_label.setText("Stalemate")
        self.board_svg = chess.svg.board(
            self.board,
            size=self.board_size,
            coordinates=self.coordinates,
            lastmove=self.last_ai_move,
            squares=king_attacked_by).encode("UTF-8")
        self.svg_widget.load(self.board_svg)
Example #23
0
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setGeometry(500, 50, 1000, 1000)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(0, 0, 1000, 1000)

        if args.board is not None:
            self.chessboard = chess.Board(args.board)
        else:
            self.chessboard = chess.Board()

        self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
        self.widgetSvg.mousePressEvent = self.onclick
        self.human_first_click = True
        self.human_move = ''

        with open(os.path.join(os.getcwd(), 'config.json'), 'r') as f:
            self.config = json.load(f)

        self.use_nn = args.nn
        self.use_database = args.database
        self.use_mcts = args.mcts

        # QTimer.singleShot(10, self.play)
        # QTimer.singleShot(10, self.play)

    def human_on_click(self, event):

        move = self.get_human_move(event)
        if move is None:
            return None
        if self.human_first_click:
            self.human_first_click = False
            self.human_move = move
        else:
            self.human_first_click = True
            self.human_move += move
            try:
                move = None
                start_position = position_to_index_1d(self.human_move[:2])
                if self.chessboard.piece_at(start_position) in [chess.Piece.from_symbol('p'),
                                                                chess.Piece.from_symbol('P')]:
                    end_position = position_to_index_1d(self.human_move[2:])
                    if start_position in [end_position + ROW_SIZE, end_position - ROW_SIZE]:
                        print('enter promotion: q, r, b, n')
                        value = input()
                        if value in ['q', 'r', 'b', 'n']:
                            move = chess.Move.from_uci(self.human_move + value)
                if move is None:
                    move = chess.Move.from_uci(self.human_move)
                if move in self.chessboard.legal_moves:
                    # check for pawn to last row move and prompt player for type of piece conversion wanted
                    return move
            except:
                pass
        return None

    def get_computer_move(self):
        if self.use_database:
            try:
                con_db = self.config['database']
                database = get_database_from_file(self.chessboard.fen(), con_db['file_path'], con_db['file_name'])
                moves, probabilities = get_fen_moves_and_probabilities(database, self.chessboard.fen())
                index = np.searchsorted(probabilities.cumsum(), np.random.rand(), side='left')
                return chess.Move.from_uci(moves[index])
            except:
                pass
        if self.use_mcts:
            import gc
            MCTS_Node.use_nn = self.use_nn
            move = mcts_move(self.chessboard)[0]
            gc.collect(generation=2)
            gc.collect(generation=1)
            gc.collect(generation=0)
            return move
        if self.use_nn:
            try:
                if self.nn_model is None:
                    from tensorflow import keras
                    self.nn_model = keras.models.load_model(self.config['train']['nn_model_path'])
                # returns the best k moves
                moves, _ = get_nn_moves_and_probabilities([self.chessboard.copy()], self.nn_model)[0]
                for m in moves:
                    if chess.Move.from_uci(m) in self.chessboard.legal_moves:
                        return chess.Move.from_uci(m)
            except:
                pass
        # if no legal move was generated use alpha beta to find one.
        return alpha_beta_move(self.chessboard)

    def onclick(self, event):

        if event.button() == QtCore.Qt.LeftButton:
            if self.chessboard.turn:
                if args.whuman:
                    move = self.human_on_click(event)
                    if move is None:
                        return
                else:
                    move = self.get_computer_move()
                    self.human_first_click = True
                print('white:', str(move))
            else:
                if args.bhuman:
                    move = self.human_on_click(event)
                    if move is None:
                        return
                else:
                    move = self.get_computer_move()
                    self.human_first_click = True
                print('black:', str(move))

            self.chessboard.push(move)
            self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
            self.widgetSvg.load(self.chessboardSvg)
            if self.chessboard.is_checkmate():
                if self.chessboard.turn:
                    print('Black Wins')
                else:
                    print('White Wins')
            if self.chessboard.is_insufficient_material():
                print('Draw - insufficient material')
            if self.chessboard.is_stalemate():
                print('Draw - stalemate')

        if event.button() == QtCore.Qt.RightButton:  # undo last move
            self.chessboard.pop()
            self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
            self.widgetSvg.load(self.chessboardSvg)
        if event.button() == QtCore.Qt.MiddleButton:
            print(self.chessboard.__repr__())

        # self.widgetSvg.update()
        # time.sleep(1)

    def get_human_move(self, event):
        SQUARE_START = 40
        SQUARE_SIZE = 115
        SQUARES_PER_ROW_COLUMN = 8

        def get_square_index(pos):
            v = (pos - SQUARE_START) // SQUARE_SIZE
            if 0 <= v < SQUARES_PER_ROW_COLUMN:
                return v
            return None

        row = get_square_index(event.x())
        if row is None:
            return None
        row = chr(ord('a') + row)
        col = get_square_index(event.y())
        if col is None:
            return None
        col = SQUARES_PER_ROW_COLUMN - col
        return str(row) + str(col)

    def play(self):
        self.widgetSvg.update()
        self.show()
        time.sleep(1)
        for i in range(3):
            move = alpha_beta_move(self.chessboard)
            self.chessboard.push(move)
            self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
            self.widgetSvg.load(self.chessboardSvg)
            self.widgetSvg.update()
            time.sleep(1)
Example #24
0
class Notification(object):
    def __init__(self,
                 window,
                 styleFunction,
                 stylesheet=["", "", ""],
                 img_margin=5,
                 top_margin=5,
                 pos=[0, 0],
                 size=[100, 20]):
        self._styleFunction = styleFunction
        self._currApp = ''
        self._pos = pos

        # Create components
        ### Notification Background
        self._background_main_stylesheet = stylesheet[0]
        self._background = QLabel(window)
        self._background.setGeometry(pos[0], pos[1], size[0], size[1])
        self._background.hide()
        ### Notification Logo
        self._logo = None
        self._logo_geometry = [
            img_margin, img_margin, size[1] - img_margin * 2,
            size[1] - img_margin * 2
        ]
        ### Notification Title
        self._title = QLabel(self._background)
        self._title.setAttribute(Qt.WA_TranslucentBackground)
        self._title.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self._title.setStyleSheet('QLabel{' + stylesheet[1] + '}')
        self._title.setText('Title')
        self._title.adjustSize()
        self._title.setGeometry(
            img_margin + self._logo_geometry[2] + 4, top_margin,
            size[0] - img_margin - self._logo_geometry[2] - 4,
            self._title.height())
        self._title.show()
        ### Notification Message
        self._message = QLabel(self._background)
        self._message.setAttribute(Qt.WA_TranslucentBackground)
        self._message.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self._message.setStyleSheet('QLabel{' + stylesheet[2] + '}')
        self._message.setText('Message')
        self._message.adjustSize()
        self._message.setGeometry(
            img_margin + self._logo_geometry[2] + 8,
            top_margin + self._title.height() + 2,
            size[0] - img_margin - self._logo_geometry[2] - 8,
            self._message.height() * 2)
        self._message.show()

    def setParent(self, p):
        self._background.setParent(p)

    def deleteLater(self):
        self._background.deleteLater()

    def setText(self, app, title, message):
        if self._currApp != app:
            logoPath, backgroundColor = self._styleFunction(app)
            if self._logo == None:
                self._logo = QSvgWidget(logoPath, self._background)
                self._logo.setGeometry(self._logo_geometry[0],
                                       self._logo_geometry[1],
                                       self._logo_geometry[2],
                                       self._logo_geometry[3])
                self._logo.show()
            else:
                self._logo.load(logoPath)
            self._background.setStyleSheet('QLabel {background-color:' +
                                           backgroundColor + ';' +
                                           self._background_main_stylesheet +
                                           '}')
            self._logo.setStyleSheet('background-color:' + backgroundColor +
                                     ';')
            self._currApp = app

        # Update Textual Contents
        self._title.setText(title)
        self._message.setText(message)
        self._message.setWordWrap(True)

    def update(self):
        self._background.update()
        self._logo.update()
        self._title.update()
        self._message.update()

    def show(self):
        self._background.show()

    def hide(self):
        self._background.hide()

    def move(self, x, y):
        self._pos = [x, y]
        self._background.move(x, y)

    def moveX(self, x):
        self._pos[0] = x
        self._background.move(x, self._pos[1])

    def moveY(self, y):
        self._pos[1] = y
        self._background.move(self._pos[0], y)

    def bringToFront(self):
        self._background.raise_()

    def bringToBack(self):
        self._background.lower()
Example #25
0
import time

from PyQt5.QtWidgets import QApplication
from PyQt5.QtSvg import QSvgWidget, QSvgRenderer
from PyQt5 import QtCore
from PyQt5.QtCore import QByteArray, QEventLoop, QTimer

import chess
import chess.svg

board = chess.Board()
board.reset_board()

app = QApplication(sys.argv)
svgWidget = QSvgWidget()
svgWidget.setGeometry(400, 300, 400, 400)
svgWidget.show()
board_picture = chess.svg.board(board)

svg_bytes = bytearray(board_picture, encoding='utf-8')
svgWidget.renderer().load(svg_bytes)
svgWidget.update()
svgWidget.show()

loop = QEventLoop()
QTimer.singleShot(1000, loop.quit)
loop.exec_()

source_cell_index = chess.square(
    chess.FILE_NAMES.index('a'),
    chess.RANK_NAMES.index('1'))  #example: A1 is cell index = 0 (out of 63)
Example #26
0
class ViewerTab(QWidget):
    def __init__(self, parent, chess_db):
        super(QWidget, self).__init__(parent)
        layout = QGridLayout(self)

        self.chess_db = chess_db

        self.setLayout(layout)
        self.current_game = None

        # textbox for locating .pgn file to open
        self.pgn_file_txt = QLineEdit(parent)
        self.pgn_file_txt.setText("Enter .pgn path here.")
        layout.addWidget(self.pgn_file_txt, 0, 0, 1, 7)

        # load file button
        self.open_file_btn = QPushButton("Load")
        self.open_file_btn.clicked.connect(self.open_file_btn_click)
        layout.addWidget(self.open_file_btn, 0, 7, 1, 1)

        # step back move button
        self.back_btn = QPushButton("<")
        self.back_btn.clicked.connect(self.back_btn_click)
        layout.addWidget(self.back_btn, 9, 2)

        # step Forward move button
        self.fwd_btn = QPushButton(">")
        self.fwd_btn.clicked.connect(self.fwd_btn_click)
        layout.addWidget(self.fwd_btn, 9, 5)

        # SVG display for board
        self.svg_widget = QSvgWidget(parent=parent)
        self.svg_widget.setGeometry(10, 10, 1000, 1000)
        layout.addWidget(self.svg_widget, 1, 0, 8, 8)
        self.board = chess.Board()
        self.paint_board()

        # listbox for games in current pgn
        self.games_list = QListWidget()
        self.games_list.clicked.connect(self.games_list_click)
        layout.addWidget(self.games_list, 0, 8, 4, 7)

        # textbox displaying current game moves
        self.engine_move_info = QPlainTextEdit(parent)
        layout.addWidget(self.engine_move_info, 4, 8, 6, 7)

    def games_list_click(self, qmodelindex):
        # set game as current selected game from list and display it
        self.current_game = self.games[self.games_list.currentRow()]
        self.engine_move_info.clear()
        self.engine_move_info.insertPlainText(str(self.current_game))

        # load in mainline moves
        self.mainline_moves = [
            move for move in self.current_game.mainline_moves()
        ]
        # used to track which move the display is currently at
        self.move_counter = 0

        # set board display to current game data
        self.board = self.current_game.board()
        self.paint_board()

    def open_file_btn_click(self):
        # get file path
        fname = QFileDialog.getOpenFileName(self, 'Open file',
                                            str(self.chess_db),
                                            "PGN files (*.pgn)")
        fname = Path(str(fname[0]))
        self.pgn_file_txt.setText(str(fname))

        if Path(self.pgn_file_txt.text()).exists() and Path(
                self.pgn_file_txt.text()).suffix == '.pgn':
            # open game file
            pgn_file = open(Path(self.pgn_file_txt.text()))
            self.games = []
            game = chess.pgn.read_game(pgn_file)
            while game is not None:
                self.games.append(game)
                game = chess.pgn.read_game(pgn_file)

            # populate list with games
            self.games_list.clear()
            game_openers = [
                g.headers.get('Opening', f'Game {i+1}')
                for i, g in enumerate(self.games)
            ]

            list_count = 0
            for opener in game_openers:
                self.games_list.insertItem(list_count, opener)
                list_count += 1

    def back_btn_click(self):
        if self.current_game is None:
            self.engine_move_info.clear()
            self.engine_move_info.insertPlainText(
                "Need to load a game! Select a .pgn file and then select a game from the list above."
            )
        else:
            if self.move_counter > 0:
                # undo last move
                self.board.pop()
                # diplay result
                self.paint_board()

                self.move_counter -= 1

    def fwd_btn_click(self):
        if self.current_game is None:
            self.engine_move_info.clear()
            self.engine_move_info.insertPlainText(
                "Need to load a game! Select a .pgn file and then select a game from the list above."
            )
        else:
            if self.move_counter < len(self.mainline_moves):
                # push the next move
                self.board.push(self.mainline_moves[self.move_counter])
                # display result
                self.paint_board()

                self.move_counter += 1

    def paint_board(self):
        self.board_SVG = chess.svg.board(self.board).encode('UTF-8')
        self.svg_widget.load(self.board_SVG)
class MainWindow(QWidget):
    """
    Create a surface for the chessboard.
    """
    def __init__(self):
        """
        Initialize the chessboard.
        """
        super().__init__()

        self.setWindowTitle("Chess GUI")
        self.setGeometry(300, 300, 610, 610)

        self.widgetSvg = QSvgWidget(parent=self)
        self.widgetSvg.setGeometry(10, 10, 600, 600)

        self.boardSize = min(self.widgetSvg.width(), self.widgetSvg.height())
        self.coordinates = True
        self.margin = 0.05 * self.boardSize if self.coordinates else 0
        self.squareSize = (self.boardSize - 2 * self.margin) / 8.0
        self.pieceToMove = [None, None]

        self.board = chess.Board()

        self.game = chess.pgn.Game()
        self.game.headers["Event"] = "test"
        self.game.headers["White"] = "user"
        self.game.headers["Black"] = "homemade engine"
        self.game.setup(self.board)
        self.node = self.game

        self.drawBoard()

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        """
        Handle left mouse clicks and enable moving chess pieces by
        clicking on a chess piece and then the target square.

        Moves must be made according to the rules of chess because
        illegal moves are suppressed.
        """
        if (event.x() <= self.boardSize) and (event.y() <= self.boardSize):
            if (event.buttons() == Qt.LeftButton):
                if (self.margin < event.x() < self.boardSize -
                        self.margin) and (self.margin < event.y() <
                                          self.boardSize - self.margin):
                    file = int((event.x() - self.margin) / self.squareSize)
                    rank = 7 - int((event.y() - self.margin) / self.squareSize)
                    square = chess.square(file, rank)
                    piece = self.board.piece_at(square)
                    coordinates = "{}{}".format(chr(file + 97), str(rank + 1))
                    if self.pieceToMove[0] is not None:
                        move = chess.Move.from_uci("{}{}".format(
                            self.pieceToMove[1], coordinates))
                        if move in self.board.legal_moves:
                            self.board.push(move)
                            self.node = self.node.add_variation(move)
                        piece = None
                        coordinates = None
                    self.pieceToMove = [piece, coordinates]
                    self.drawBoard()
                    if self.board.is_game_over() == True:
                        self.game.headers["Result"] = self.board.result()
                        pgn = open('test_game.pgn', 'w', encoding='utf-8')
                        exporter = chess.pgn.FileExporter(pgn)
                        self.game.accept(exporter)

    def drawBoard(self):
        """
        Draw a chessboard with the starting position and then redraw
        it for every new move.
        """
        self.boardSvg = self.board._repr_svg_().encode("UTF-8")
        self.drawBoardSvg = self.widgetSvg.load(self.boardSvg)

        return self.drawBoardSvg
Example #28
0
class MainWindow(QWidget):
    move_signal = pyqtSignal()

    def __init__(self):
        super().__init__()

        self.setWindowTitle("Zachy's Chess")
        self.setGeometry(300, 300, 700, 700)

        self.widgetSvg = QSvgWidget(parent=self)
        self.svgX = 50  # top left x-pos of chessboard
        self.svgY = 50  # top left y-pos of chessboard
        self.cbSize = 600  # size of chessboard
        self.widgetSvg.setGeometry(self.svgX, self.svgY, self.cbSize,
                                   self.cbSize)
        self.coordinates = True

        self.margin = 0.05 * self.cbSize if self.coordinates == True else 0
        self.squareSize = (self.cbSize - 2 * self.margin) / 8.0
        # Layout
        self.vbox = QVBoxLayout()
        self.vbox.setContentsMargins(295, 300, 295, 300)
        self.setLayout(self.vbox)
        # Init game
        self.initializeGame()
        self.move_signal.connect(self.newMove)

    def initializeGame(self):
        # Chess game
        self.modeChange(0)
        self.game = Game(self.game_mode, autoplay=True)
        self.chessboard = self.game.board
        self.selectedPiece = None
        self.pieceToMove = [None, None]
        self.next_move = None
        # Starting Screen
        self.startBtn = QPushButton('Start', self)
        self.startBtn.resize(self.startBtn.sizeHint())
        self.startBtn.clicked.connect(self.startButtonEvent)
        self.modeSelector = QComboBox()
        self.modeSelector.addItems(GAME_MODES)
        self.modeSelector.currentIndexChanged.connect(self.modeChange)
        self.vbox.addWidget(self.modeSelector)
        self.vbox.addWidget(self.startBtn)

    def modeChange(self, idx):
        self.game_mode = _GAME_MODES[idx]

    def startButtonEvent(self, event):
        self.startBtn.hide()
        self.modeSelector.hide()
        self.modeSelector.setFocusPolicy(Qt.NoFocus)  # FIXME: Doesnt solve it
        self.game = Game(self.game_mode, autoplay=True)
        self.chessboard = self.game.board
        self.update()
        if self.game_mode == "auto":
            # self.hint = QLabel("Press the spacebar to move")
            # self.hint.resize(self.hint.sizeHint())
            self.move_signal.emit()
        elif self.game_mode == "white-auto":
            self.move_signal.emit()

    def replayButtonEvent(self):
        self.result.hide()
        self.replayBtn.hide()
        self.initializeGame()

    def newMove(self):
        # TODO: Show illegal move (unselect?), etc.
        try:
            legal, result = self.game.play(self.next_move)
        except ValueError:  # User clicked on same square twice
            # legal, result = self.game.play('0000')
            return

        if legal:
            self.update()
        if result is not None:
            self.gameOver(RESULTS[result])

    def gameOver(self, message):
        # FIXME: Box Overflows
        self.result = QLabel(message)
        self.result.setAlignment(Qt.AlignCenter)
        self.result.resize(self.result.sizeHint())
        self.result.setStyleSheet("background-color:white; border-radius:5px")
        self.replayBtn = QPushButton('Replay', self)
        self.replayBtn.resize(self.replayBtn.sizeHint())
        self.replayBtn.clicked.connect(self.replayButtonEvent)
        self.vbox.addWidget(self.result)
        self.vbox.addWidget(self.replayBtn)

    @pyqtSlot(QWidget)
    def mousePressEvent(self, event):
        if self.svgX < event.x(
        ) <= self.svgX + self.cbSize and self.svgY < event.y(
        ) <= self.svgY + self.cbSize:  # mouse on chessboard
            if event.buttons() == Qt.LeftButton and self.game_mode != "auto":
                # if the click is on chessBoard only
                if self.svgX + self.margin < event.x(
                ) < self.svgX + self.cbSize - self.margin and self.svgY + self.margin < event.y(
                ) < self.svgY + self.cbSize - self.margin:
                    file = int((event.x() - (self.svgX + self.margin)) /
                               self.squareSize)
                    rank = 7 - \
                        int((event.y() - (self.svgY + self.margin))/self.squareSize)
                    if self.game_mode == "white-auto":  # if white is on top
                        file = 7 - file
                        rank = 7 - rank
                    square = chess.square(file, rank)
                    piece = self.chessboard.piece_at(square)
                    coordinates = '{}{}'.format(chr(file + 97), str(rank + 1))

                    self.selectedPiece = None
                    if self.pieceToMove[0] is not None:
                        self.next_move = self.pieceToMove[1] + coordinates
                        self.move_signal.emit()
                        piece = None
                        coordinates = None
                    elif piece is not None:
                        if piece.color == self.game.white_next:  # True if both white or both black
                            self.selectedPiece = square

                    self.pieceToMove = [piece, coordinates]
                else:
                    print('coordinates clicked')
                # Envoke the paint event.
                self.update()
        else:
            QWidget.mousePressEvent(self, event)

    @pyqtSlot(QWidget)
    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.close()
        elif event.key() == Qt.Key_Space and self.game_mode == "auto":
            self.move_signal.emit()
        else:
            QWidget.keyPressEvent(self, event)

    @pyqtSlot(QWidget)
    def paintEvent(self, event):
        flipped = True if self.game_mode == 'white-auto' else False
        self.chessboardSvg = chess.svg.board(self.chessboard,
                                             size=self.cbSize,
                                             coordinates=self.coordinates,
                                             check=self.selectedPiece,
                                             flipped=flipped).encode("UTF-8")
        self.widgetSvg.load(self.chessboardSvg)
Example #29
0
class Result(QWidget):
    def __init__(self, parent=None):
        super(Result, self).__init__(parent)
        self.capture = Capture(None)
        self.draw = Canvas(None)
        self.setAcceptDrops(True)
        self.setWindowIcon(QIcon("favicon.ico"))
        # region WindowSettings
        self.setFixedWidth(600)
        self.setWindowTitle("MathPix+")
        self.setWindowFlags(Qt.MSWindowsFixedSizeDialogHint
                            | Qt.WindowCloseButtonHint
                            | Qt.WindowStaysOnTopHint)
        # endregion
        # region Svg
        self.svg_container = QWidget()
        self.svg_container.setFixedSize(QSize(578, 200))
        self.svg = QSvgWidget(self.svg_container)
        # endregion
        # region Info Label
        self.label = QLabel()
        self.label.setFont(QFont("等线", 20))
        self.label.setMaximumHeight(30)
        self.label.setAlignment(Qt.AlignCenter)
        # endregion
        # region Image
        self.img = QLabel()
        self.img.setFixedSize(578, 200)
        self.img.setAlignment(Qt.AlignCenter)
        # endregion
        # region TeX LineEdit
        self.tex = QLineEdit()
        self.tex.setAlignment(Qt.AlignCenter)
        self.tex.setFont(QFont("Cambria Math", 20))
        self.tex.setMaximumHeight(60)
        self.tex.setPlaceholderText("Enter Your Tex Here")
        self.tex.setEchoMode(QLineEdit.Normal)
        self.tex.textChanged.connect(self.on_tex_changed)
        # endregion
        # region PushButtons
        self.save_as_raw_tex = QPushButton("&Raw")
        self.save_as_raw_tex.setFixedHeight(40)
        self.save_as_raw_tex.setFont(QFont("等线", 20))
        self.save_as_raw_tex.clicked.connect(
            lambda: self.copy_tex_to_clipboard(""))
        self.save_as_inline_tex = QPushButton("&Inline")
        self.save_as_inline_tex.setFixedHeight(40)
        self.save_as_inline_tex.setFont(QFont("等线", 20))
        self.save_as_inline_tex.clicked.connect(
            lambda: self.copy_tex_to_clipboard("$"))
        self.save_as_block_tex = QPushButton("&Block")
        self.save_as_block_tex.setFixedHeight(40)
        self.save_as_block_tex.setFont(QFont("等线", 20))
        self.save_as_block_tex.clicked.connect(
            lambda: self.copy_tex_to_clipboard("$$"))
        self.open_img = QPushButton("&Open")
        self.open_img.setFixedHeight(40)
        self.open_img.setFont(QFont("等线", 20))
        self.open_img.clicked.connect(lambda: self.get_tex(self.get_img()))
        self.snap_img = QPushButton("&Snap")
        self.snap_img.setFixedHeight(40)
        self.snap_img.setFont(QFont("等线", 20))
        self.snap_img.clicked.connect(self.capture_img)
        self.draw_img = QPushButton("&Draw")
        self.draw_img.setFixedHeight(40)
        self.draw_img.setFont(QFont("等线", 20))
        self.draw_img.clicked.connect(self.canvas_img)
        # endregion
        # region Layout
        self.copy_hlo = QHBoxLayout()
        self.open_hlo = QHBoxLayout()
        self.copy_hlo.addWidget(self.save_as_raw_tex)
        self.copy_hlo.addWidget(self.save_as_inline_tex)
        self.copy_hlo.addWidget(self.save_as_block_tex)
        self.open_hlo.addWidget(self.open_img)
        self.open_hlo.addWidget(self.snap_img)
        self.open_hlo.addWidget(self.draw_img)
        self.vlo = QVBoxLayout()
        self.vlo.addWidget(self.svg_container)
        self.vlo.addWidget(self.img)
        self.vlo.addWidget(self.label)
        self.vlo.addWidget(self.tex)
        self.vlo.addLayout(self.copy_hlo)
        self.vlo.addLayout(self.open_hlo)
        # endregion
        self.get_tex("")
        self.setLayout(self.vlo)

    def on_tex_changed(self):
        try:
            parser = math_text.MathTextParser('svg')
            parser.parse(r"$" + self.tex.text() + r"$")
        except ValueError:
            self.label.setText("TeX语法不正确")
        else:
            self.label.setText('')
            self.generate_svg(self.tex.text())

    def copy_tex_to_clipboard(self, string):
        clipboard = QApplication.clipboard()
        clipboard.setText(string + self.tex.text() + string)
        self.label.setText("TeX已复制至剪贴板")

    def generate_svg(self, raw_tex):
        fig = Figure(figsize=(5, 4), dpi=300)
        canvas = FigureCanvasAgg(fig)
        fig.text(.5, .5, r"$" + raw_tex + r"$", fontsize=40)
        fig.savefig("output.svg", bbox_inches="tight", facecolor=(1, 1, 1, 0))
        self.svg.load("output.svg")
        renderer = QSvgRenderer('output.svg').defaultSize()
        w = renderer.width()
        h = renderer.height()
        if w / h > 578 / 200:
            display_w = 578
            display_h = int(578 * h / w)
        else:
            display_h = 200
            display_w = int(200 * w / h)
        self.svg.setFixedWidth(display_w)
        self.svg.setFixedHeight(display_h)
        self.svg.setGeometry(
            QRect(289 - int(display_w / 2), 100 - int(display_h / 2),
                  display_w, display_h))

    def get_img(self):
        file_name, file_type = QFileDialog.getOpenFileName(
            self, "选取图片", "./", "所有文件 (*);;图片文件 (*.jpg *.png)")
        print(file_name, file_type)
        return file_name

    def get_tex(self, url=r"limit.jpg"):
        if url == "":
            self.set_data("limit.jpg",
                          r"\lim_{x\rightarrow3}(\frac{x^{2}+9}{x-3})", 1)
            return
        with open(url, 'rb') as pic:
            base64_data = base64.b64encode(pic.read())
            print(base64_data)
        img_url = "data:image/jpg;base64," + base64_data.decode()
        r = requests.post("https://api.mathpix.com/v3/latex",
                          data=json.dumps({'url': img_url}),
                          headers={
                              "app_id": "******",
                              "app_key": "********************************",
                              "Content-type": "application/json"
                          })
        print(json.dumps(json.loads(r.text), indent=4, sort_keys=True))
        try:
            raw_data = json.loads(r.text)
        except AttributeError:
            return
        else:
            if "latex" in raw_data:
                tex = raw_data["latex"]
            else:
                return
            if "latex_confidence" in raw_data:
                confidence = raw_data["latex_confidence"]
            else:
                confidence = 1

            self.set_data(url, tex, confidence)

    def set_data(self, img, tex, con):
        raw_img = QPixmap(img)
        w = raw_img.width()
        h = raw_img.height()
        if w / h > 578 / 200:
            self.img.setPixmap(
                raw_img.scaledToWidth(578, Qt.SmoothTransformation))
        else:
            self.img.setPixmap(
                raw_img.scaledToHeight(200, Qt.SmoothTransformation))

        tex_data = tex
        tex_data = tex_data.replace(r"\\", "\\")
        tex_data = tex_data.replace(' ', '')
        self.tex.setText(tex_data)
        self.generate_svg(tex_data)

        if con < 0.8:
            self.label.setText("置信值低于0.8, 建议进行人工校对 : ")

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        print("dropped")
        url = str(event.mimeData().urls()[0].toLocalFile())
        print(url)
        self.get_tex(url)

    def capture_img(self):
        self.capture.grab_new_img()
        self.capture.show()
        self.capture.captured.connect(lambda: self.get_tex("capture.jpg"))

    def canvas_img(self):
        self.draw.show()
        self.draw.drawn.connect(lambda: self.get_tex("canvas.jpg"))
Example #30
0
class App(QMainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.initUi()

        self.cheme = ChemeObject()
        # Переменные для хранения индексов на удаление
        self.craneListItem = [0]
        self.fermListItem = [0]

        # инициализация диалоговых окон
        self.addCraneWindow = addCraneDialog(self)
        self.addFermWindow = addFermDialog(self)
        self.addHeightPointWindow = addHeightPointDialog(self)

        # Биндинги полей формы к объекту
        self.ui.CalcNumber.setText(str(self.cheme.calcNumber))
        self.ui.Owner.setText(str(self.cheme.owner))
        self.ui.PathLength.setText(str(self.cheme.pathLength))
        self.ui.PathWidth.setText(str(self.cheme.pathWidth))
        self.ui.DimentionStep.setText(str(self.cheme.dimentionStep))
        self.ui.RailName1.setText(str(self.cheme.railOneName))
        self.ui.RailName2.setText(str(self.cheme.railTwoName))
        self.ui.PathStartName.setText(str(self.cheme.pathStartName))
        self.ui.PathCancelName.setText(str(self.cheme.pathCancelName))

        # Инициализация таблицы высотных отметок
        self.tablePlanePoint = self.ui.TablePlanePoint
        self.tablePlanePoint.setColumnCount(4)
        self.tablePlanePoint.setRowCount(0)

        self.tablePlanePoint.setHorizontalHeaderLabels([
            "№№ \n точек",
            "Условная\nотметка\nрельс {0}".format(self.ui.RailName1.text()),
            "Условная\nотметка\nрельс {0}".format(self.ui.RailName2.text()),
            "Колея\n+- 15 мм."
        ])
        self.updatePlanePointTable()
        self.tablePlanePoint.verticalHeader().hide()

    def initUi(self):
        """
        Инициализация интерфейса пользователя
        """
        # Подключение файла формы
        self.ui = uic.loadUi("./ui/HeightPlan-Main.ui")

        # Нажатие на кнопку генерации картинок
        self.ui.GenerateCheme.clicked.connect(self.generateCheme)

        # Кнопки вызова диалоговых окон
        self.ui.AddCrane.clicked.connect(self.addCraneDialog)
        self.ui.AddFerm.clicked.connect(self.addFermDialog)
        self.ui.AddPlanePoint.clicked.connect(self.addPlanePointDialog)

        # Кнопки для работы со списком кранов
        self.ui.ClearCraneList.clicked.connect(self.clearChemeCran)
        self.ui.DeleteCrane.clicked.connect(self.deleteSelectedCrane)

        # Кнопки для работы со списком ферм
        self.ui.ClearFermList.clicked.connect(self.clearChemeFerm)
        self.ui.DeleteFerm.clicked.connect(self.deleteSelectedFerm)

        # Кнопки для работы с таблицей точек
        self.ui.ClearPlanePoint.clicked.connect(self.clearPlanePoint)

        pathLengtValidator = QIntValidator(0, 3000000, self)
        pathWidthValidator = QIntValidator(0, 150000, self)
        dimentionStepValidator = QIntValidator(0, 25000, self)

        self.ui.PathLength.setValidator(pathLengtValidator)
        self.ui.PathWidth.setValidator(pathWidthValidator)
        self.ui.DimentionStep.setValidator(dimentionStepValidator)
        # Вызов слота после окончания ввода значения, перекидываем значение в объект
        self.ui.CalcNumber.editingFinished.connect(self.__updateCalcNumber)
        self.ui.Owner.editingFinished.connect(self.__updateOwner)
        self.ui.PathLength.editingFinished.connect(self.__updatePathLength)
        self.ui.PathWidth.editingFinished.connect(self.__updatePathWidth)
        self.ui.DimentionStep.editingFinished.connect(
            self.__updateDimentionStep)
        self.ui.RailName1.editingFinished.connect(self.__updateRailName1)
        self.ui.RailName2.editingFinished.connect(self.__updateRailName2)
        self.ui.PathStartName.editingFinished.connect(
            self.__updatePathStartName)
        self.ui.PathCancelName.editingFinished.connect(
            self.__updatePathCancelName)

        # Сигналы списков
        self.ui.CraneList.itemClicked.connect(self.craneListSelectItem)
        self.ui.FermList.itemClicked.connect(self.fermListSelectItem)

        # Инициализация SVG графики
        self.shemePreviewLayout = self.ui.ChemePreviewLayout
        self.defectShemePreviewLayout = self.ui.DefectChemePreviewLayout

        # Показываем окно пользователю
        self.ui.show()

    def generateCheme(self):
        chemes = ChemeSvgGenerator(self.cheme)
        chemes.generate()
        self.shemeSvgShemeWidget = QSvgWidget("{0} {1} - Deffects.svg".format(
            self.cheme.calcNumber, self.cheme.owner))
        self.shemeSvgShemeWidget.setGeometry(500, 500, 850, 850)
        self.shemePreviewLayout.addWidget(self.shemeSvgShemeWidget)
        self.shemeSvgShemePreviewWidget = QSvgWidget(
            "{0} {1} - Cheme.svg".format(self.cheme.calcNumber,
                                         self.cheme.owner))
        self.shemeSvgShemePreviewWidget.setGeometry(500, 500, 850, 850)
        self.defectShemePreviewLayout.addWidget(self.shemeSvgShemeWidget)

    def checkPoints(self):
        if self.cheme.totalPoints == len(self.cheme.planePointList):
            return True
        else:
            return False

    def updateCraneList(self):
        """
        Метод обновляет список кранов
        """
        self.ui.CraneList.clear()
        if self.cheme.craneList:
            for crane in self.cheme.craneList:
                self.ui.CraneList.addItem(
                    "№поз.: <{2}> \tЗав.№ {0} \t Грузоподъемность: {1}".format(
                        crane.numberCrane, crane.liftingCapacityCrane,
                        crane.pointPositionCrane))

            self.ui.ClearCraneList.setEnabled(True)
        else:
            self.ui.DeleteCrane.setEnabled(False)
            self.ui.ClearCraneList.setEnabled(False)

    def craneListSelectItem(self, item):
        """
        Обработчик выделения
        """
        position = str(re.findall(r'<\d{1,3}>', item.text()))
        self.craneListItem[0] = int(position[3:-3])
        self.ui.DeleteCrane.setEnabled(True)

    def deleteSelectedCrane(self):
        """
        Удаление выделенный кра из списка кранов
        """
        for crane in self.cheme.craneList:
            if crane.pointPositionCrane == int(self.craneListItem[0]):
                self.cheme.craneList.remove(crane)
                self.ui.DeleteCrane.setEnabled(False)
        self.updateCraneList()

    def clearChemeCran(self):
        """
        Обработчик кнопки очистки списка кранов
        """
        self.cheme.craneList.clear()
        self.updateCraneList()

    def addCraneDialog(self):
        """
        Открывает модальное окно с добавлением крана в схему
        """
        self.addCraneWindow.updatePlanePointsOptions()
        self.addCraneWindow.show()
        res = self.addCraneWindow.exec_()

        if res == QDialog.Accepted:
            # Обновляем список кранов
            self.updateCraneList()

    def updateFermList(self):
        """
        Метод обновляет список ферм
        """
        self.ui.FermList.clear()
        if self.cheme.fermList:
            for ferm in self.cheme.fermList:
                self.ui.FermList.addItem(
                    "№поз.: <{0}>\tФерма тормозная".format(
                        ferm.pointPositionFerm))
            self.ui.ClearFermList.setEnabled(True)
        else:
            self.ui.DeleteFerm.setEnabled(False)
            self.ui.ClearFermList.setEnabled(False)

    def fermListSelectItem(self, item):
        """
        Обработчик выделения фермы
        """
        position = str(re.findall(r'<\d{1,3}>', item.text()))
        self.fermListItem[0] = int(position[3:-3])
        self.ui.DeleteFerm.setEnabled(True)

    def deleteSelectedFerm(self):
        """
        Удаление выделенную ферму из списка ферм
        """
        for ferm in self.cheme.fermList:
            if ferm.pointPositionFerm == int(self.fermListItem[0]):
                self.cheme.fermList.remove(ferm)
                self.ui.DeleteFerm.setEnabled(False)
        self.updateFermList()

    def clearChemeFerm(self):
        """
        Обработчик кнопки очистки списка ферм
        """
        self.cheme.fermList.clear()
        self.updateFermList()

    def addFermDialog(self):
        """
        Открывает модальное окно с добавлением ферм в схему
        """
        self.addFermWindow.updatePlanePointsOptions()
        self.addFermWindow.show()
        res = self.addFermWindow.exec_()
        if res == QDialog.Accepted:
            self.updateFermList()

    def clearPlanePoint(self):
        """
        Полностью очищает весь список точек
        """
        self.cheme.planePointList.clear()
        self.updatePlanePointTable()

    def updatePlanePointTable(self):
        """
        Обновляет отображение данных в таблице высотных отметок
        """
        self.tablePlanePoint.setRowCount(len(self.cheme.planePointList))
        for i in range(0, len(self.cheme.planePointList)):
            self.tablePlanePoint.setItem(
                i, 0,
                QTableWidgetItem(
                    str(self.cheme.planePointList[i].pointPosition)))
            self.tablePlanePoint.setItem(
                i, 1,
                QTableWidgetItem(
                    str(self.cheme.planePointList[i].heightRailOne)))
            self.tablePlanePoint.setItem(
                i, 2,
                QTableWidgetItem(
                    str(self.cheme.planePointList[i].heightRailTwo)))
            self.tablePlanePoint.setItem(
                i, 3,
                QTableWidgetItem(str(self.cheme.planePointList[i].widthPlane)))
        self.tablePlanePoint.resizeColumnsToContents()

    def addPlanePointDialog(self):
        """
        Открывает модальное окно с добавлением точки в схему
        """
        self.addHeightPointWindow.updatePlanePointsOptions()
        self.addHeightPointWindow.show()
        res = self.addHeightPointWindow.exec_()
        if res == QDialog.Accepted:
            self.updatePlanePointTable()
            self.ui.ClearPlanePoint.setEnabled(True)
            if self.checkPoints():
                self.ui.GenerateCheme.setEnabled(True)
            else:
                self.ui.GenerateCheme.setEnabled(False)

    def openFileDialog(self):
        """
        Открытие ранее сохраненного файла со схемой
        """
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(
            self, "Открыть файл схемы", "",
            "Все файлы (*);; Файл схемы (*.hep)")

    @pyqtSlot()
    def __updateCalcNumber(self):
        """
        Слот обновляет поле CalcNumber в объекте cheme
        """
        self.cheme.calcNumber = self.ui.CalcNumber.text()

    @pyqtSlot()
    def __updateOwner(self):
        """
        Слот обновляет поле CalcNumber в объекте cheme
        """
        self.cheme.owner = self.ui.Owner.text()

    @pyqtSlot()
    def __updatePathLength(self):
        """
        Слот обновляет длину пути в объекте cheme
        """
        if int(self.ui.PathLength.text()) <= self.cheme.dimentionStep:
            QMessageBox.warning(
                self, "Ошибка.",
                "Длинна пути не может быть меньше шага замера. Измените длину пути или шаг измерения."
            )
        else:
            self.cheme.pathLength = self.ui.PathLength.text()

    @pyqtSlot()
    def __updatePathWidth(self):
        """
        Слот обновляет ширину пролета в объекте cheme
        """
        self.cheme.pathWidth = self.ui.PathWidth.text()

    @pyqtSlot()
    def __updateDimentionStep(self):
        """
        Слот обновляет шаг измерения в объекте cheme
        """
        if int(self.ui.DimentionStep.text()) > self.cheme.pathLength:
            QMessageBox.warning(
                self, "Ошибка.",
                "Шаг замера не может быть Больше длинны пути. Измените длину пути или шаг измерения."
            )
        else:
            self.cheme.dimentionStep = self.ui.DimentionStep.text()

    @pyqtSlot()
    def __updateRailName1(self):
        """
        Слот обновляет имя первой ости рельс в объекте cheme
        """
        self.cheme.railOneName = self.ui.RailName1.text()

    @pyqtSlot()
    def __updateRailName2(self):
        """
        Слот обновляет имя второй оси рельс в объекте cheme
        """
        self.cheme.railTwoName = self.ui.RailName2.text()

    @pyqtSlot()
    def __updatePathStartName(self):
        """
        Слот обновляет название стартовой оси в объекте cheme
        """
        self.cheme.pathStartName = self.ui.PathStartName.text()

    @pyqtSlot()
    def __updatePathCancelName(self):
        """
        Слот обновляет название конечной оси в объекте cheme
        """
        self.cheme.pathCancelName = self.ui.PathCancelName.text()