'PyQT5 - mix VBox and HBox Layout?
I created the following windows which generally works fine:
from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog,
QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,
QVBoxLayout)
import sys
class Dialog(QDialog):
NumGridRows = 3
NumButtons = 4
def __init__(self):
super(Dialog, self).__init__()
self.createFormGroupBox()
self.Button1 = QPushButton(self)
self.Button1.setText("Calc")
self.Button2 = QPushButton(self)
self.Button2.setText("Reset")
# buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
# buttonBox.accepted.connect(self.accept)
# buttonBox.rejected.connect(self.reject)
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.formGroupBox)
# mainLayout.addWidget(buttonBox)
mainLayout.addWidget(self.Button1)
mainLayout.addWidget(self.Button2)
self.setLayout(mainLayout)
self.setWindowTitle("Form Layout")
def createFormGroupBox(self):
self.formGroupBox = QGroupBox("Form layout")
layout = QFormLayout()
layout.addRow(QLabel("Name:"), QLineEdit())
layout.addRow(QLabel("Country:"), QComboBox())
layout.addRow(QLabel("Age:"), QSpinBox())
self.formGroupBox.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Dialog()
sys.exit(dialog.exec_())
The only thing I would like to change is that the buttons are horizontally arranged under the form layout and not vertically.
How can I achieve that to mix a vertical box with a horizontally box inside?
Solution 1:[1]
A Qt layout manager is a "container" of QLayoutItems, which are abstract items that represent visual objects that can be layed out.
Those items usually contain a Qt widget, but they can also be other objects, like spacers (QSpacerItem) or even other layouts (note that QLayout actually inherits from QLayoutItem).
You can actually do nested layouts.
The solution to your problem is actually pretty easy:
- create a horizontal layout;
- add the buttons to that layout;
- add the layout to the main layout;
class Dialog(QDialog):
NumGridRows = 3
NumButtons = 4
def __init__(self):
super(Dialog, self).__init__()
self.setWindowTitle("Form Layout")
self.createFormGroupBox()
# QLayout(widget) automatically sets the layout on "widget" so you
# don't need to call widget.setLayout()
mainLayout = QVBoxLayout(self)
mainLayout.addWidget(self.formGroupBox)
self.button1 = QPushButton("Calc")
self.button2 = QPushButton("Reset")
buttonLayout = QHBoxLayout()
buttonLayout.addWidget(self.button1)
buttonLayout.addWidget(self.button2)
mainLayout.addLayout(buttonLayout)
Notes:
- when widgets are going to be added to a layout, there's no point in providing the widget argument (
self, in this case), as adding them to a layout that is set on a widget automatically reparents them; - only classes and constants should have capitalized names, not variables, functions or instance attributes (that's why I changed
button1andbutton2); remember that readability is very important, see the official Style Guide for Python Code to know more; - QDialogButtonBox is a QWidget on its own, with its internal layout; you can still use it for custom buttons, though; for instance, you could change the text of the
Okbutton doingbuttonBox.button(buttonBox.Ok).setText("Calc"); or you could add a custom button by doingokButton = QPushButton("Calc")andbuttonBox.addButton(okButton, buttonBox.AcceptRole); please carefully study the documentation to better understand the behavior of that class;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

