Reputation: 123
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())
Upvotes: 0
Views: 655
Reputation:
You don't need call setup_widgets
and setup_layout
from your B. __init__
since they are already called by A.
Upvotes: 0