2017-11-14 4 views
0

Ich entwickle eine Schach-GUI in Python 3.6.3 mit PyQt5 5.9.1 (GUI-Framework) und python-chess 0.21.1 (Schach-Bibliothek) auf Windows 10. Ich möchte den Wert eines Stückes erhalten, das auf ein SVG-Schachbrett geklickt wurde (zur Verfügung gestellt von python-chess), so dass ich dieses Stück dann zu einem anderen Quadrat bewegen kann.Klicken Sie auf Schachfigur aus einem SVG-Schachbrett

Nach dem ersten Klick mit der linken Maustaste und dem Abrufen des Stücks möchte ich den zweiten linken Mausklick vom Benutzer erhalten und das Quadrat erhalten, auf das der Benutzer geklickt hat. Dann muss meine Schach-GUI das Stück vom Ursprungsquadrat zum Zielquadrat bewegen.

Also, hier ist mein vollständiger Arbeitscode bisher. Hinweise oder Ergänzungen sind sehr willkommen.

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

Antwort

1

Wenn Größe Schachbrett bekannt ist, können Sie die Koordinaten des per Mausklick aus event.pos() resp.event.x() finden, event.y() je nach marginwidth und squaresize finden Schach. svg.py Zeile 129 ff.

bearbeiten 25. November:event.pos() ist in diesem Beispiel in Mainwindow-Koordinaten, auf Schachbrett die Koordinaten zu finden, durch self.svgX und self.svgY dargestellt von links oben berechnet werden müssen:

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

bewegen weiß und schwarz abwechselnd wechseln sie die Farbe, wenn die gleiche Farbe zweimal bewegt wird.

+0

Wie würde ich gehen und die Regeln implementieren? So kann sich Weiß/Schwarz nicht zweimal oder öfter bewegen. Zuerst bewegt sich Weiß und dann Schwarz. Auch dürfen Schachfiguren nicht zufällig auf dem Spielbrett platziert werden, sondern nach den Regeln des Schachspiels. Ich weiß, dass Python-Schach diese 'chess.Board(). Is_valid()' Funktion hat, ich weiß einfach nicht wo genau ich es setzen soll. Durch die Implementierung der Funktion 'is_valid()' stellen wir alternative Stückzüge (Weiß, Schwarz ...) sicher und sorgen dafür, dass die Teile nach Schachregeln bewegt werden. Auch, wie kann ich diese Farbverlauf auf dem King's Square implementieren, wenn es in Schach ist? –

+0

siehe [Readthedocs] (https://python-chess.readthedocs.io/en/latest/) –

+0

Wie auch immer, danke für Ihre Lösung! Ich schätze die Hilfe sehr. Ich habe allerdings eine Frage. Warum ist das notwendig? 'sonst: QWidget.mousePressEvent (self, event)'? –

0

Unten ist die Python, PyQt5 und python-chess Code für eine voll funktionsfähige schach GUI, die Rechts bewegen Erkennung eingebaut hat, so Bewegung Schachfigur verhält sich auf die Regeln des Schachspiels nach.

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