PyQt5 - добавить AbstractButton в макет
Я делаю карточную игру 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 ответ
Согласно документам:
Чтобы создать подкласс 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_()