简体   繁体   中英

Inheriting from custom PyQt5 QWidget does not call parent method

I am coding a little application in PyQt5 and came across a problem illustrated at hand of the following minimal working example:

My custom class 'A' inherits from the QWidget class, calls two setup methods (one for widgets and one for layouts) and adds the widgets from the setup_widgets method ('Click A' Button) to the Layout called 'frame'. This works fine and creating a QApplication as well as a QMainWindow and adding such a class A widget to it will display it properly.

However in the next step I design a class 'B' which is supposed to inherit from class 'A'. Hence I call the init method of 'A' within the init method of 'B'. To my understanding this will go through A. init () including the A.setup_widgets() as well as A.setup_layout(), which adds the 'Click A' Button as well as a Layout called 'frame' to the object. After a little of debugging though I noticed that the call of setup_layout that comes from the A. init () does actually call the B.setup_layout since the 'self' argument of the inheritance call seems to be an object of type 'B'. Therefore an Error is raised since for the B object no Layout called 'frame' was ever created.

A workaround would be to add A.setup_widgets(self) as a first line to the B.setup_widgets method, equivalently adding A.setup_layout(self) to B.setup_layout method. This approach is also shown in the source code, but commented with a #. However this results in an attempt to set a QLayout twice and thus in a Warning/Error:

QWidget::setLayout: Attempting to set QLayout "" on B "", which already has a layout.

What is the proper way to deal with this issue of inheritance? If it helps: I never plan to use class A as an actual object, still would like it to be a solo standing functioning class since I will derive many different subclasses from it.

Thanks and cheers, Paul

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

您不需要从B. __init__调用setup_widgetssetup_layout ,因为它们已被A调用。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM