Layout management group (Layouts)
What is layout manager? You usually have many widgets in a window, right? If you want to adjust their position and size by yourself, it will be more troublesome. Moreover, when the window becomes larger, the widgets in it will not become larger, which is very troublesome. Therefore, we have this thing, the layout manager, which is equivalent to a small housekeeper. As long as you throw in the widgets, he will arrange them for you.
method:
First, create the widgets we want to layout.
Then we create a QBoxLayout object and add widgets to the layout.
Finally, we call QWidget::setLayout() to install the QBoxLayout object on the widget.
At this point, the widget in the layout will reset its parent object to the window that called setLayout() above.
1. BoxLayout
QBoxLayout can arrange controls horizontally or vertically, and derives QHBoxLayout and QVBoxLayout subclasses respectively.
QHBoxLayout: horizontal layout, which arranges controls horizontally, i.e. left and right. QVBoxLayout: vertical layout, which arranges the controls in the vertical direction, that is, up and down.
The horizontal layout and vertical layout are the same except for the different directions (LeftToRight and TopToBottom) during construction.
Public function
Serial number | Function & Description |
---|---|
1 | void addLayout(QLayout * layout,int # stretch = 0) adds layout to the end of the box and stretches with a continuous stretch factor. |
2 | void addSpacerItem(QSpacerItem * spacerItem) adds spaceritem to the end of the box layout. Usually, this function is not used. Please use addSpacing(int size) |
3 | void addSpacing(int size) adds a non scalable space (QSpacerItem) of size to the end of the box layout |
4 | void addStretch(int # stretch = 0) adds a scalable space (a QSpacerItem), the minimum size is zero, and the stretch factor stretches to the end of the box layout. |
5 | void addStrut(int size) limits the minimum vertical size of the box to size |
6 | void addWidget(QWidget * widget,int:: stretch = 0,Qt::Alignment = 0) adds the widget to the end of this box layout and stretches and aligns it using the stretch factor. |
7 | void setDirection(QBoxLayout::Direction) sets the direction of this layout to direction. |
8 | void setSpacing(int # spacing) sets the spacing between widgets |
9 | void setStretch(int # index,int # stretch) sets the stretch factor stretch for the control at the index position |
10 | bool setStretchFactor(QWidget * widget,int stretch) bool setStretchFactor(QWidget * widget,int stretch) sets the stretch factor of the widget. If the widget is found in the layout (excluding the sub layout), it returns true; Otherwise, false is returned. |
Let's take QHBoxLayout as an example to explain the common functions of QBoxLayout.
-
Simple layout
//Create widgets that require layout QLabel* nameLabel = new QLabel("name"); QLineEdit* nameEdit = new QLineEdit; //Create layout QBoxLayout* hlayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); //Add widgets to layout hlayout->addWidget(nameLabel); hlayout->addWidget(nameEdit); //Sets the layout for the current window this->setLayout(hlayout);
-
Layout nesting
//Name QLabel* nameLabel = new QLabel("Name"); QLineEdit* nameEdit = new QLineEdit; QBoxLayout* nameHlayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); nameHlayout->addWidget(nameLabel); nameHlayout->addWidget(nameEdit); //Telephone QLabel* phoneLabel = new QLabel("Phone"); QLineEdit* phoneEdit = new QLineEdit; QBoxLayout* phoneHlayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight); phoneHlayout->addWidget(phoneLabel); phoneHlayout->addWidget(phoneEdit); //Layout nesting QBoxLayout* mainlayout = new QBoxLayout(QBoxLayout::Direction::TopToBottom); mainlayout->addLayout(nameHlayout); mainlayout->addLayout(phoneHlayout); this->setLayout(mainlayout);
Basic use
-
Create five buttons and add them to the horizontal layout
QPushButton *btn1 = new QPushButton("One"); QPushButton *btn2 = new QPushButton("Two"); QPushButton *btn3 = new QPushButton("Three"); QPushButton *btn4 = new QPushButton("Four"); QPushButton *btn5 = new QPushButton("Five"); QHBoxLayout* hlayout = new QHBoxLayout; hlayout->addWidget(btn1); hlayout->addWidget(btn2); hlayout->addWidget(btn3); hlayout->addWidget(btn4); hlayout->addWidget(btn5); this->setLayout(hlayout);
-
Set margin
void setMargin(int margin); void setContentsMargins(int left,int top,int right,int bottom);
Here I use setMargin(0) to set the outer margin to 0.
-
Set spacing
void setSpacing(int spacing)
-
Add extruded space (QSpacerItem)
QHBoxLayout* hlayout = new QHBoxLayout; hlayout->addStretch(); //Add extruded space hlayout->addWidget(btn1); ...
Add scaling before the first control, so that all controls will be displayed on the right.
Add scaling after the last control, so that all controls will be displayed on the left.
Add scaling before the first control and after the last space, so that all controls will be centered.
-
Add control addWidget
void addWidget(QWidget *widget, int stretch = 0, Qt::Alignment alignment = 0)
By default, it is aligned in the center. If we set the height of one of the buttons a little higher, we can see that it is very obvious~
Use the down and up controls to set the other controls.
QHBoxLayout* hlayout = new QHBoxLayout; hlayout->addStretch(); //Add extruded space hlayout->addWidget(btn1,0,Qt::AlignmentFlag::AlignTop); hlayout->addWidget(btn2,0,Qt::AlignmentFlag::AlignTop); hlayout->addWidget(btn3,0); hlayout->addWidget(btn4,0,Qt::AlignmentFlag::AlignBottom); hlayout->addWidget(btn5,0,Qt::AlignmentFlag::AlignBottom);
-
Set layout direction
void setDirection(QBoxLayout::Direction direction) //You can set from left to right, from right to left, from top to bottom, from bottom to top, etc...
setDirection(QBoxLayout::RightToLeft)
setDirection(QBoxLayout::TopToBottom);
Since QHBoxLayout is used, it is generally not recommended to use TopToBottom or BottomToTop. If the direction cannot be determined or can be changed at will, it is recommended to use QBoxLayout.
Set stretch factor
When the size of the form changes, the control will adjust accordingly according to the stretching coefficient.
//Set the stretching factor of the widget. If a widget (excluding child layouts) is found in the layout, return true; Otherwise, false is returned. bool setStretchFactor(QWidget *widget, int stretch) bool setStretchFactor(QLayout *layout, int stretch) hlayout->setStretchFactor(btn2,1); hlayout->setStretchFactor(btn3,2);
Set the stretching coefficient of btn2 to 1 and btn3 to 2. When the window becomes larger, btn3 will be stretched first. When it reaches a certain degree, btn2 will be stretched again. The width ratio of btn2 to btn3 is 1:2.
2. GridLayout
Grid layout is also called grid layout (multi row and multi column)
QGridLayout takes up the space available to it (through its parent layout or parentWidget()), divides it into rows and columns, and puts each widget it manages in the correct cell.
Columns and rows behave the same; We will discuss columns, but rows also have equivalent functions.
Each column has a minimum width and a stretch factor. The minimum width is the maximum width set using setColumnMinimumWidth() and the minimum width of each widget in the column. The stretch factor is set using setColumnStretch() and determines how much free space the column will get exceeds or exceeds the minimum necessary space.
Public function
Serial number | Function & Description |
---|---|
2 | Void addlayout (qlayout * layout, int row, int column, QT:: alignment = 0) void addlayout (qlayout * layout, int row, int column, int rowSpan, int columnSpan, QT:: alignment = 0) places the layout in the grid (row, column). The position of the upper left corner is (0,0). Span multiple rows / columns. The cell will start with rows and columns that span rowSpan rows and columnSpan columns. |
3 | Void addwidget (QWidget * widget, int row, int column, QT:: alignment = 0) void addwidget (QWidget * widget, int fromrow, int fromcolumn, int rowspan, int columnspan, QT:: alignment = 0) is the same as above |
4 | void setRowStretch(int # row, int # stretch) sets the stretch factor of row to stretch |
5 | void setColumnStretch(int # column, int # stretch) sets the stretch factor of the column to stretch |
6 | Void setrow minimumheight (int row, int minSize) sets the minimum width of the row to minSize pixels. |
7 | Void setcolumnminimumwidth (int column, int minSize) sets the minimum width of the column to minSize pixels. |
QLabel* imageLabel = new QLabel; QLineEdit* userNamaeEdit = new QLineEdit; QLineEdit* passwdEdit = new QLineEdit; QCheckBox* rememberCheckBox = new QCheckBox; QCheckBox* autoLoginCheckBox = new QCheckBox; QPushButton* registerBtn = new QPushButton; QPushButton* forgetBtn = new QPushButton; QPushButton* loginBtn = new QPushButton; //Set picture imageLabel->setFixedSize(90,90); imageLabel->setPixmap(QPixmap("://images/loginIcon.png")); imageLabel->setScaledContents(true); //Set input box userNamaeEdit->setPlaceholderText("QQ number/mobile phone/mailbox"); passwdEdit->setPlaceholderText("password"); //Set check box rememberCheckBox->setText("Remember the password"); autoLoginCheckBox->setText("automatic logon"); //Set button registerBtn->setText("Registered account"); forgetBtn->setText("Retrieve password"); loginBtn->setText("Sign in"); QGridLayout* layout = new QGridLayout; layout->addWidget(imageLabel,0,0,3,1); layout->addWidget(userNamaeEdit,0,1,1,2); layout->addWidget(registerBtn,0,3); layout->addWidget(passwdEdit,1,1,1,2); layout->addWidget(forgetBtn,1,3); layout->addWidget(rememberCheckBox,2,1); layout->addWidget(autoLoginCheckBox,2,2); layout->addWidget(loginBtn,3,1,1,2); layout->setHorizontalSpacing(10); layout->setVerticalSpacing(10); layout->setContentsMargins(20,20,20,20); this->setLayout(layout);
3. Form layout
The QFormLayout class manages the form of the input widget and its associated tags
QFormLayout is a convenient layout class that arranges its children in two columns. The left column consists of labels and the right column consists of field widgets (row editor, spin box, etc.). Traditionally, this two column form layout is implemented using QGridLayout.
QFormLayout is a higher-level alternative with the following advantages:
-
Follow the look and feel guidelines of different platforms. For example, the macOS Aqua and KDE guidelines specify that labels should be right aligned, while Windows and GNOME applications usually use left alignment.
-
Support long line wrap
For devices with smaller display, QFormLayout can be set to wrap long lines, or even all lines.
-
There is a very convenient API for creating label field pairs. We can create a QLabel and QWidget control line with a given text through addrow (const qstring & labelText, QWidget * field), which can be automatically set as a partnership.
Public function
Serial number | Function & Description |
---|---|
1 | void addRow(QWidget * label,QWidget * field) void addRow(QWidget * label,QLayout * field) adds a new line at the bottom of the form layout using the given label and field |
2 | Void addrow (const qstring & labelText, QWidget * field) void addrow (const qstring & labelText, qlayout * field) this overload will automatically create a QLabel with labelText as text in the background. Field is set as the partner of the new QLabel |
3 | void addRow(QWidget *widget) void addRow(QLayout* layout) adds the specified widget at the end of the form layout. This widget spans two columns |
9 | void setRowWrapPolicy(QFormLayout::RowWrapPolicy policy) true |
10 | void setSpacing(int spacing) sets the vertical and horizontal spacing to spacing. |
11 | Void setverticalspating (int spacing) sets the vertical spacing to spacing |
12 | Void setwidget (int row, qformlayout:: itemrole, role, QWidget * widget) sets the role in the given row as a widget, and uses a blank line to expand the layout if necessary. If the cell is already occupied, the widget is not inserted and an error message is sent to the console. |
QLineEdit* userEdit = new QLineEdit; QLineEdit* passwdEdit = new QLineEdit; QPushButton* loginBtn = new QPushButton("determine"); QFormLayout* fromLayout = new QFormLayout; fromLayout->addRow("userName:",userEdit); fromLayout->addRow("password:",passwdEdit); fromLayout->addWidget(loginBtn); this->setLayout(fromLayout);
Compare it with the following code written using QGridLayout:
QLineEdit* userEdit = new QLineEdit; QLineEdit* passwdEdit = new QLineEdit; QPushButton* loginBtn = new QPushButton("determine"); QLabel*userLabel = new QLabel("userName:"); QLabel*passwdLabel = new QLabel("passwdEdit:"); QGridLayout* glayout = new QGridLayout; glayout->addWidget(userLabel,0,0); glayout->addWidget(userEdit,0,1); glayout->addWidget(passwdLabel,1,0); glayout->addWidget(passwdEdit,1,1); glayout->addWidget(loginBtn,2,1); this->setLayout(glayout);
-
Set line feed policy void setRowWrapPolicy(QFormLayout::RowWrapPolicy policy)
enumeration describe effect QFormLayout::DontWrapRows Fields are always placed next to their labels (default style) QFormLayout::WrapLongRows The label has enough space to adapt. If the minimum size of the field pair is greater than the available space, the input box will be changed to the next line QFormLayout::WrapAllRows Fields are always under their labels. -
Set the control void setWidget(int row, QFormLayout::ItemRole role, QWidget *widget)
-
Set the widget in the given row of a given role as a widget and expand the layout with empty rows if necessary.
-
content | value | describe |
---|---|---|
QFormLayout::LabelRole | 0 | label |
QFormLayout::FieldRole | 1 | field |
QFormLayout::SpanningRole | 2 | Widgets across label and field columns |
QFormLayout * flayout = new QFormLayout; flayout->setWidget(0,QFormLayout::ItemRole::LabelRole,new QLabel("LabelRole")); flayout->setWidget(0,QFormLayout::ItemRole::FieldRole,new QLineEdit("FieldRole")); flayout->setWidget(1,QFormLayout::ItemRole::SpanningRole,new QPushButton("SpanningRole")); this->setLayout(flayout);
4. Stack layout
QStackedLayout inherits from QLayout.
QStackedLayout class provides the layout of multi page switching. You can only see one interface at a time.
QStackedLayout can be used to create a user interface similar to that provided by QTabWidget. There is also a convenience class QStackedWidget based on QStackedLayout
sngnals
//This signal is emitted whenever the current widget in the layout changes. Index specifies the index of the new current widget, or - 1 if there is no new widget void currentChanged(int index) //This signal is emitted whenever a widget is deleted from the layout, and inded is the deleted index. void widgetRemoved(int index)
slots
void setCurrentIndex(int index) void setCurrentWidget(QWidget *widget)
Public function
Serial number | Function & Description |
---|---|
2 | int addWidget(QWidget *widget) add widgets to the layout |
5 | int insertWidget(int index, QWidget *widget) inserts the widget into the specified subscript |
6 | void setStackingMode(QStackedLayout::StackingMode stackingMode) sets how child widget visibility is handled. |
5. Splitter
The QSplitter class implements a separate widget. Splitter allows users to control the size of subassemblies by dragging the boundaries between them. Any number of widgets can be controlled by a single splitter. A typical use of QSplitter is to create several widgets and add them using insertWidget() or addWidget().
QSplitter *splitter = new QSplitter(this); splitter->addWidget(new QTextBrowser); splitter->addWidget(new QTextBrowser); splitter->addWidget(new QTextBrowser); splitter->setHandleWidth(2); splitter->setCollapsible(0,false); QSplitter *sp = new QSplitter(Qt::Orientation::Vertical,splitter); sp->addWidget(new QTextBrowser); sp->addWidget(new QTextBrowser);
search
copy