2017-11-14 9 views
0

私はPyQt5 5.9.1(GUIフレームワーク)とpython-chess 0.21.1(チェスライブラリ)をWindows 10に使って、Python 3.6.3のチェスのGUIを開発しています。私はSVGチェス盤(python-chessで提供)でクリックされた作品の価値を得て、その作品を別の広場に移動することができます。SVGチェス盤からクリックしてください

最初のマウスを左クリックしてピースを取得した後、ユーザーから2番目のマウスの左クリックを取得し、ユーザーがクリックした四角形を取得します。その後、私のチェスのGUIは、元の四角形から目標の四角形にピースを移動させる必要があります。

ここまでは完全な作業コードです。ヒントや実際のコードの追加は大歓迎です。

#! /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() 

答えて

1

チェス盤の大きさがわかっている場合、あなたはMARGINWIDTHとsquaresizeに応じて、()resp.event.x()、event.y()event.posからマウスクリックの座標を見つけることができますが、チェスを参照してください。 svg.py行129ff。

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() 

移動白と黒:event.pos()メインウィンドウにチェスボード上の座標を全てself.svgXself.svgYで表される左上隅から計算されなければならないを見つけるために、座標この例である:11月25

編集同じ色を2回動かすと色が変わります。

+0

どうすればルールを実装できますか?白/黒は2回以上動かすことができません。最初は白と黒を移動します。また、チェスピースをボード上にランダムに配置するのではなく、チェスのルールで配置する必要があります。私はpython-chessにこの 'chess.Board()。is_valid()'関数があることを知っています。私は正確にどこに置くべきか分かりません。 'is_valid()'関数を実装することで、代替ピースの動き(White、Black ...)を保証し、チェスのルールに従ってピースを移動させるようにします。 また、キングススクエアにそのグラデーションカラーを実装するにはどうしたらいいですか? –

+0

[Readthedocs](https://python-chess.readthedocs.io/en/latest/)をご覧ください。 –

+0

とにかく、ありがとうございます!私は本当に助けに感謝します。私は1つの質問を持っている。 これはなぜ必要なのですか? 'else: QWidget.mousePressEvent(self、event)'? –

0

法的な動き検出機能が組み込まれた完全に機能的なチェスGUIのための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_()) 
関連する問題