简体   繁体   English

PyQt5-将AbstractButton添加到布局

[英]PyQt5 - add AbstractButton to layout

I'm making a Solitaire card game to practice OOP and PyQt5, and I'm having trouble adding a card, which inherits QAbstractButton , to a layout ( QGridLayout , QHBoxLayout , or QVBoxLayout ). 我正在制作纸牌纸牌游戏来练习OOP和PyQt5,但在将继承QAbstractButton的纸牌添加到布局( QGridLayoutQHBoxLayoutQVBoxLayout )时遇到了麻烦。 Here is part of the Card object: 这是Card对象的一部分:

class Card(QAbstractButton):    

    def __init__(self, rank=None, suit=None, parent=None):
        super().__init__(parent)
        self.rank = rank
        self.suit = suit
        self.visibility = False

    def paintEvent(self, e):
        painter = QPainter()
        painter.begin(self)
        if self.visibility == True:
            self.draw_card_front(painter)
        else:
            self.draw_card_back(painter)
        painter.end()

    def draw_card_back(self, painter):
        painter.setPen(COLOR_OUTLINE)
        painter.setBrush(COLOR_BACK)
        painter.drawRoundedRect(0, 0, CARD_WIDTH-1, CARD_HEIGHT-1, 10, 10)

    def draw_card_front(self, painter):
        painter.setPen(COLOR_OUTLINE)
        painter.setBrush(COLOR_FRONT)
        painter.drawRoundedRect(0, 0, CARD_WIDTH-1, CARD_HEIGHT-1, 10, 10)

        self.draw_rank(painter)
        self.draw_suit(painter)

    ...

And here is the game's class: 这是游戏的类:

class Solitaire(QWidget):

    def __init__(self):
        super().__init__()
        self.score = 0

        self.initUI()


    def initUI(self):
        grid = QGridLayout()
        self.setLayout(grid)

        self.card1 = Card(rank=1, suit=2, parent=self)
        self.card2 = Card(rank=1, suit=2, parent=self)

        grid.addWidget(self.card1, 0, 0)
        grid.addWidget(self.card2, 1, 0)

        self.setWindowTitle('Yay')
        self.setGeometry(300, 300, 400, 400)
        self.show()

    ...

if __name__ == '__main__':
    app = QApplication(sys.argv)
    game = Solitaire()
    app.exec_()

When I run the program, the Card does not show up. 当我运行该程序时,该Card不会显示。 But if I don't use a layout, the Card shows up normally. 但是,如果我不使用布局,则Card会正常显示。 And if I try adding a QPushButton to a layout it works fine, too. 如果我尝试将QPushButton添加到布局中,它也可以正常工作。 I feel like I'm missing something with the parent property, or perhaps I'm not overloading a function from QAbstractButton in the Card class. 我感觉好像缺少了parent属性,或者我没有在Card类中重载QAbstractButton中的函数。 Can anyone advise? 有人可以建议吗?

According to the docs : 根据文档

To subclass QAbstractButton, you must reimplement at least paintEvent() to draw the button's outline and its text or pixmap. 要继承QAbstractButton,必须至少重新实现paintEvent()才能绘制按钮的轮廓及其文本或像素图。 It is generally advisable to reimplement sizeHint() as well, and sometimes hitButton() (to determine whether a button press is within the button). 通常建议重新实现sizeHint() ,有时也重新实现hitButton()(以确定按钮是否在按钮内)。 For buttons with more than two states (like tri-state buttons), you will also have to reimplement checkStateSet() and nextCheckState(). 对于具有两个以上状态的按钮(例如三状态按钮),还必须重新实现checkStateSet()和nextCheckState()。

From the above we conclude that you must implement the paintEvent() method that is responsible for drawing the button, this depends on what you want to draw, and the sizeHint() method which is the size used by the layouts. 从以上内容可以得出结论,您必须实现负责绘制按钮的paintEvent()方法,这取决于您要绘制的内容,以及sizeHint()方法(即布局使用的大小)。

For example: 例如:

import sys

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class Card(QAbstractButton):    

    def __init__(self, rank=None, suit=None, parent=None):
        super().__init__(parent)
        self.rank = rank
        self.suit = suit
        self.visibility = False

    def sizeHint(self):
        return QSize(100, 100)

    def paintEvent(self, e):
        painter = QPainter(self)
        if self.visibility:
            self.draw_card_front(painter)
        else:
            self.draw_card_back(painter)

    ...

class Solitaire(QWidget):

    def __init__(self):
        super().__init__()
        self.score = 0

        self.initUI()


    def initUI(self):
        grid = QGridLayout()
        self.setLayout(grid)

        self.card1 = Card(rank=1, suit=2, parent=self)
        self.card2 = Card(rank=1, suit=2, parent=self)

        grid.addWidget(self.card1, 0, 0)
        grid.addWidget(self.card2, 1, 0)

        self.setWindowTitle('Yay')
        self.setGeometry(300, 300, 400, 400)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    game = Solitaire()
    app.exec_()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM