从自定义PyQt5 QWidget继承不会调用父方法

时间:2019-05-15 08:08:29

标签: python inheritance pyqt5

我在PyQt5中编写了一个小应用程序,遇到了以下最小工作示例说明的问题:

我的自定义类'A'继承了QWidget类,调用了两种设置方法(一种用于小部件,一种用于布局),并将小部件从setup_widgets方法(单击'Click A'按钮)添加到称为'frame'的布局中。这样可以正常工作,并创建QApplication和QMainWindow并向其添加此类A小部件即可正确显示它。

但是,在下一步中,我设计了一个类'B',该类应该继承自'A'类。因此,我将“ B”的“ init ”方法称为“ A”的“ init ”方法。据我了解,这将通过A. init ()进行,其中包括A.setup_widgets()以及A.setup_layout(),后者会添加“点击A”按钮以及名为“框”到对象。 经过一些调试之后,我注意到来自A. init ()的setup_layout调用实际上确实调用了B.setup_layout,因为继承调用的'self'参数似乎是一个类型为“ B”的对象。因此,由于没有为B对象创建称为“框架”的布局,因此引发了错误。

一种解决方法是将A.setup_widgets(self)作为第一行添加到B.setup_widgets方法中,等效地将A.setup_layout(self)添加到B.setup_layout方法中。源代码中也显示了这种方法,但是用#注释。但是,这导致尝试两次设置QLayout,从而导致出现警告/错误:

QWidget :: setLayout:尝试在已经具有布局的B“”上设置QLayout“”。

处理此继承问题的正确方法是什么? 如果有帮助:我从不打算将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 :(得分:0)

您不需要从setup_widgets呼叫setup_layoutB. __init__,因为它们已经被A呼叫。