Я пишу небольшое приложение на PyQt5 и столкнулся с проблемой, проиллюстрированной под рукой из следующего минимального рабочего примера:
Мой пользовательский класс «A» наследуется от класса QWidget, вызывает два метода установки (один для виджетов и один для макетов) и добавляет виджеты из метода setup_widgets (кнопка «Нажмите A») в макет, называемый «фрейм» , Это прекрасно работает, и создается QApplication, а также QMainWindow, и добавление в него такого виджета класса A будет правильно отображать его.
Однако на следующем шаге я создаю класс «B», который должен наследоваться от класса «A». Поэтому я вызываю init метод 'A' в рамках init метода 'B'. Насколько я понимаю, это будет проходить через A. init (), включая A.setup_widgets (), а также A.setup_layout (), который добавляет кнопку «Click A» и рамку «Layout». к объекту.
После небольшой отладки я заметил, что вызов setup_layout, который поступает из A. init (), действительно вызывает B.setup_layout, так как аргумент 'self' вызова наследования кажется объектом типа «В». Поэтому возникает ошибка, поскольку для объекта B макет с именем frame не создавался.
Обходным решением будет добавить A.setup_widgets (self) в качестве первой строки в метод B.setup_widgets, эквивалентно добавив A.setup_layout (self) в метод B.setup_layout. Этот подход также показан в исходном коде, но прокомментирован знаком #. Однако это приводит к попытке установить QLayout дважды и, следовательно, к предупреждению / ошибке:
QWidget :: setLayout: Попытка установить QLayout "" на B "", который уже имеет макет.
Как правильно решать эту проблему наследования?
Если это поможет: я никогда не планирую использовать класс A в качестве фактического объекта, но все же хотел бы, чтобы он был автономным функциональным классом, поскольку я буду выводить из него много различных подклассов.
Спасибо и ура,
Пол
from PyQt5.QtWidgets import *
class A(QWidget):
def __init__(self):
QWidget.__init__(self)
self.setup_widgets()
self.setup_layout()
def setup_widgets(self):
self.button_a = QPushButton('Click A')
def setup_layout(self):
self.frame = QHBoxLayout()
self.frame.addWidget(self.button_a)
self.setLayout(self.frame)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = QMainWindow()
wid = A()
win.setCentralWidget(wid)
win.show()
sys.exit(app.exec())
----------------------------------------------- --------------------------
from PyQt5.QtWidgets import *
from class_a import A
class B(A):
def __init__(self):
A.__init__(self)
self.setup_widgets()
self.setup_layout()
def setup_widgets(self):
#A.setup_widgets(self)
self.button_b = QPushButton('Click B')
def setup_layout(self):
#A.setup_layout(self)
self.frame.addWidget(self.button_b)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = QMainWindow()
wid = B()
win.setCentralWidget(wid)
win.show()
sys.exit(app.exec())