I am new to pyqt and trying to create a set of nested containers which hold my controls. I could not find any examples that nest widgets(and keep them layouted). I was able to nest layouts only, but thats not what i want to achieve. One reason i want to do this, is to have controle over the backgroundcolor of my containers. Since layouts do not have a color, i think i need QWidgets or QFrames. This is how far i came:
class AssetCreationWindow(QtWidgets.QMainWindow):
def __init__(self):
super(AssetCreationWindow, self).__init__()
self.create_content()
self.show()
def create_content(self):
# creating main container-frame, parent it to QWindow
self.main_CF = QtWidgets.QFrame(self)
self.main_CF.setStyleSheet('background-color: rgba(255, 0, 0, 1);')
self.setCentralWidget(self.main_CF)
# creating layout and parent it to main container
# is it correct, that main_CL now manages children of main_CF ?
self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)
# creating the first subcontainer + layout, parenting it
asset_CGF = QtWidgets.QFrame(self.main_CF)
asset_CGF.setStyleSheet('background-color: rgba(0, 255, 0, 1);')
asset_CGL = QtWidgets.QHBoxLayout(asset_CGF)
# creating label and lineEdit, both are supposed to be on top of asset_CGF
asset_label = QtWidgets.QLabel("Assetname: ", asset_CGF)
asset_CGL.addWidget(asset_label)
asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
asset_CGL.addWidget(asset_name)
# doing the same with a second container
department_CGF = QtWidgets.QFrame(self.main_CF)
department_CGF.setStyleSheet('background-color: rgba(0, 0, 255, 1);')
department_CGL = QtWidgets.QHBoxLayout(department_CGF)
department_label = QtWidgets.QLabel("Department: ", department_CGF)
department_CGL.addWidget(department_label)
department_names = QtWidgets.QComboBox(department_CGF)
department_CGL.addWidget(department_names)
Unfortunatly this approach stacks all Widgets in the top right corner on top of each other. Another one was to remove the ParentWidget from all Layouts except main_CL and use addLayout().
def create_content(self):
self.main_CF = QtWidgets.QFrame(self)
self.setCentralWidget(self.main_CF)
self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)
asset_CGF = QtWidgets.QFrame(self.main_CF)
asset_CGF.setStyleSheet('background-color: rgba(255, 0, 0, 1);')
asset_CGL = QtWidgets.QHBoxLayout()
self.main_CL.addLayout(asset_CGL)
asset_label = QtWidgets.QLabel("Asset Name: ", asset_CGF)
asset_CGL.addWidget(asset_label)
asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
asset_CGL.addWidget(asset_name)
department_CGF = QtWidgets.QFrame(self.main_CF)
department_CGF.setStyleSheet('background-color: rgba(0, 255, 0, 1);')
department_CGL = QtWidgets.QHBoxLayout()
self.main_CL.addLayout(department_CGL)
department_label = QtWidgets.QLabel("Department: ", department_CGF)
department_CGL.addWidget(department_label)
department_names = QtWidgets.QComboBox(department_CGF)
department_CGL.addWidget(department_names)
This looks better in general but the subcontainer layouts seem to no know about the subcontainers. Even though the controlers are parented to the subcontainers, the controlers are not ontop of the subcontainers. The subcontainers are again stacked at the top right corner. I am at my wit's end.
Including Aleš Erjavecs answer, this is the working codeexample:
class AssetCreationWindow(QtWidgets.QMainWindow):
def __init__(self, controller):
super(AssetCreationWindow, self).__init__()
self.controller = controller
self.create_content()
self.show()
def create_content(self):
# creating main container-frame, parent it to QWindow
self.main_CF = QtWidgets.QFrame(self)
self.main_CF.setStyleSheet('background-color: rgba(150, 0, 0, 1);')
self.setCentralWidget(self.main_CF)
# creating layout and parent it to main container
# is it correct, that main_CL now manages children of main_CF ?
self.main_CL = QtWidgets.QVBoxLayout(self.main_CF)
# creating the first subcontainer + layout, parenting it
asset_CGF = QtWidgets.QFrame(self.main_CF)
self.main_CL.addWidget(asset_CGF)
asset_CGF.setStyleSheet('background-color: rgba(0, 150, 0, 1);')
asset_CGL = QtWidgets.QHBoxLayout(asset_CGF)
# creating label and lineEdit, both are supposed to be on top of asset_CGF
asset_label = QtWidgets.QLabel("Assetname: ", asset_CGF)
asset_CGL.addWidget(asset_label)
asset_name = QtWidgets.QLineEdit("MyNewAsset", asset_CGF)
asset_CGL.addWidget(asset_name)
# doing the same with a second container
department_CGF = QtWidgets.QFrame(self.main_CF)
self.main_CL.addWidget(department_CGF)
department_CGF.setStyleSheet('background-color: rgba(0, 0, 150, 1);')
department_CGL = QtWidgets.QHBoxLayout(department_CGF)
department_label = QtWidgets.QLabel("Department: ", department_CGF)
department_CGL.addWidget(department_label)
department_names = QtWidgets.QComboBox(department_CGF)
department_CGL.addWidget(department_names)
It results in this: window with nested QWidgets
You have to set the layout to the widget. E.g
self.main_CL = QtWidgets.QVBoxLayout()
self.main_CF.setLayout(self.main_CL)
Then add the subwidgets into the layout explicitly. E.g.
self.main_CL.addWidget(self.asset_CGF)
Follow the same pattern for sub components.
self.asset_CGF.setLayout(self.asset_CGL)
self.asset_CGL.addWidget(...)
Actually your first example is only missing two calls
self.main_CL.addWidget(self.asset_CGF)
self.main_CL.addWidget(department_CGF)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With