PyQt5 - добавить AbstractButton в макет - PullRequest
0 голосов
/ 24 мая 2018

Я делаю карточную игру Solitaire для практики ООП и PyQt5, и у меня возникают проблемы с добавлением карты, которая наследует QAbstractButton, в макет (QGridLayout, QHBoxLayout или QVBoxLayout),Вот часть объекта 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)

    ...

А вот класс игры:

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

Когда я запускаю программу, Card не отображается.Но если я не использую макет, Card отображается нормально.И если я попытаюсь добавить QPushButton в макет, он тоже работает хорошо.Мне кажется, что я что-то упускаю со свойством parent, или, возможно, я не перегружаю функцию из QAbstractButton в классе Card.Кто-нибудь может посоветовать?

1 Ответ

0 голосов
/ 24 мая 2018

Согласно документам :

Чтобы создать подкласс QAbstractButton, вы должны переопределить как минимум paintEvent () , чтобы нарисовать контур кнопки и ее текст илипиксельная.Как правило, рекомендуется также переопределить sizeHint () , а иногда и hitButton () (чтобы определить, находится ли нажатие кнопки внутри кнопки).Для кнопок с более чем двумя состояниями (например, кнопки с тремя состояниями) вам также придется переопределить checkStateSet () и nextCheckState ().

Исходя из вышеизложенного, мы заключаем, что вы должны реализовать paintEvent() метод, который отвечает за рисование кнопки, это зависит от того, что вы хотите нарисовать, и метод sizeHint(), который является размером, используемым макетами.

Например:

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