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
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")
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)
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)
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)
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
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)
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_())
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())
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
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()
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)
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)
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()
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!')
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, ])
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)
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_())
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())
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
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)
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)
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()
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)
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
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)
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"))
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()