我正在Python 3.6.3中使用PyQt5 5.9.1 (GUI框架)和Windows 10上的python-chess 0.21.1 (象棋库)开发一个国际象棋图形用户界面。我希望得到一个在SVG棋盘(由python-chess提供)上点击的部分的值,这样我就可以将它移动到另一个方格了。
在第一次鼠标左键点击并获得片段后,我希望从用户那里得到第二次鼠标左键,并得到用户单击的方块。然后我的国际象棋图形用户界面必须将棋子从原始方块移动到目标方块。
到目前为止,这是我完整的工作代码。任何提示或实际的代码添加都非常欢迎。
#! /usr/bin/env python3
import chess
import chess.svg
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QApplication, QWidget
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Chess Titan")
self.setGeometry(300, 300, 800, 800)
self.widgetSvg = QSvgWidget(parent=self)
self.widgetSvg.setGeometry(10, 10, 600, 600)
self.chessboard = chess.Board()
@pyqtSlot(QWidget)
def mousePressEvent(self, event):
if event.buttons() == Qt.LeftButton:
## How to get the clicked SVG chess piece?
# Envoke the paint event.
self.update()
@pyqtSlot(QWidget)
def paintEvent(self, event):
self.chessboardSvg = chess.svg.board(self.chessboard).encode("UTF-8")
self.widgetSvg.load(self.chessboardSvg)
if __name__ == "__main__":
chessTitan = QApplication([])
window = MainWindow()
window.show()
chessTitan.exec()发布于 2017-11-16 12:06:19
如果棋盘的大小是已知的,您可以从event.pos() Res.Ev.x(),event.y()中找到mouseclick的坐标,这取决于边沿宽度和平方大小,请参见chess.svg.py第129 ff行。
编辑11月25日:在本例中, event.pos()位于MainWindow坐标中,要查找棋盘上的坐标,必须从self.svgX和self.svgY表示的左上角计算出所有的坐标:
import chess
import chess.svg
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QApplication, QWidget
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()
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
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)
if __name__ == "__main__":
chessTitan = QApplication([])
window = MainWindow()
window.show()
chessTitan.exec()移动白色和黑色的部分交替,他们改变颜色,如果相同的颜色被移动两次。
发布于 2017-11-16 19:00:31
下面是一个功能齐全的国际象棋图形用户界面的Python、PyQt5和python-chess代码,它内置了合法的移动检测,因此棋子的运动是按照国际象棋的规则进行的。
#! /usr/bin/env python
"""
This module is the execution point of the chess GUI application.
"""
import sys
import chess
from PyQt5.QtCore import pyqtSlot, Qt
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import QApplication, QWidget
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)
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
if __name__ == "__main__":
chessGui = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(chessGui.exec_())发布于 2019-09-08 18:28:17
a_manthey_67和Boštjan Mejak,我结合了两种解决方案的特性:https://github.com/vtad4f/chess-ui/blob/master/board.py
完整版本集成了AI播放器与您的董事会用户界面:
https://stackoverflow.com/questions/47287328
复制相似问题