Наследование от пользовательского PyQt5 QWidget не вызывает родительский метод - PullRequest
0 голосов
/ 15 мая 2019

Я пишу небольшое приложение на 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())

1 Ответ

0 голосов
/ 15 мая 2019

Вам не нужно звонить setup_widgets и setup_layout с вашего B. __init__, так как они уже вызваны A.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...