C++客户端Qt开发——常用控件(布局管理器)
创始人
2025-01-08 19:33:21
0

7.布局管理器

之前使用Qt在界面上创建的控件,都是通过"绝对定位"的方式来设定的

也就是每个控件所在的位置,都需要计算坐标,最终通过setGeometry或者

move方式摆放过去,

这种设定方式其实并不方便,尤其是界面如果内容比较多,不好计算,而且一个窗口大小往往是可以调整的,按照绝对定位的方式,也无法自适应窗口大小

因此Qt引入"布局管理器"(Layout)机制,来解决上述问题.

布局管理器并非Qt独有.其他的GUI开发框架,像Android,前端等也有类似的机制

①垂直布局

使用QVBoxLayout表示垂直的布局管理器,V是vertical的缩写

属性

说明

layoutLeftMargin

左侧边距

layoutRightMargin

右侧边距

layoutTopMargin

上方边距

layoutBottomMargin

下方边距

layoutSpacing

相邻元素之间的间距

Layout只是用于界面布局,并没有提供信号,

①使用QVBoxLayout管理多个控件

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");     QPushButton* btn3 = new QPushButton("按钮3");      //创建布局管理器,并把按钮添加进去     //如果创建的时候指定父元素为this,则后面不需要setLayout方法了     QVBoxLayout* layout = new QVBoxLayout();     layout->addWidget(btn1);     layout->addWidget(btn2);     layout->addWidget(btn3);      //把布局管理器设置到Widget中     this->setLayout(layout);  }  Widget::~Widget() {     delete ui; }  

②创建两个QVBoxLayout

按钮已经自动排列好,只不过当前这些按钮的位置不能随着窗口大小自动变化

通过Qt Designer创建的布局管理器,其实是先创建了一个widget,.设置过geometry属性的,再把这个layout设置到这个widget

实际上,一个widget只能包含一个layout

打开ui文件的原始ml,可以看到其中的端倪

这种情况下layout并非是窗口widget的布局管理器,因此不会随着窗口大小改变

②水平布局

使用QHBox Layout,表示垂直的布局管理器.H是horizontal的缩写

核心属性(和QVBoxLayout属性是一致的)

属性

说明

layoutLeftMargin

左侧边距

layoutRightMargin

右侧边距

layoutTopMargin

上方边距

layoutBottomMargin

下方边距

layoutSpacing

相邻元素之间的间距

①使用QHBoxLayout管理控件

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      //创建三个按钮,并且把按钮添加到布局控制器中     QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");     QPushButton* btn3 = new QPushButton("按钮3");      //创建布局管理器     QHBoxLayout* layout = new QHBoxLayout();     layout->addWidget(btn1);     layout->addWidget(btn2);     layout->addWidget(btn3);      this->setLayout(layout);  }  Widget::~Widget() {     delete ui; }  

②嵌套下的layout

Layout里面可以再嵌套上其他的layout,从而达到更复杂的布局效果

#include "widget.h" #include "ui_widget.h" #include #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      //创建顶层layout     QVBoxLayout* layoutParent = new QVBoxLayout();     this->setLayout(layoutParent);      //添加两个按钮进去     QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");      layoutParent->addWidget(btn1);     layoutParent->addWidget(btn2);      //创建子layout      QHBoxLayout* layoutChild = new QHBoxLayout();      //添加两个按钮进去     QPushButton* btn3 = new QPushButton("按钮3");     QPushButton* btn4 = new QPushButton("按钮4");      layoutChild->addWidget(btn3);     layoutChild->addWidget(btn4);      //把子layout添加到父layout中     layoutParent->addLayout(layoutChild); }  Widget::~Widget() {     delete ui; }  

③网格布局

Qt中还提供了QGridLayout用来实现网格布局的效果.可以达到M*N的这种网格的效果

核心属性

整体和QVBoxLayout以及QHBoxLayout相似,但是设置spacing的时候是按照垂直水平两个方向来设置的

属性

说明

layoutLeftMargin

左侧边距

layoutRightMargin

右侧边距

layoutTopMargin

上方边距

layoutBottomMargin

下方边距

layoutHorizontalSpacing

相邻元素之间水平方向的间距

layoutVerticalSpacing

相邻元素之间垂直方向的间距

layoutRowStretch

行方向的拉伸系数

layoutColumnStretch

列方向的拉伸系数

①使用QGridLayout管理元素

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      //创建四个按钮     QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");     QPushButton* btn3 = new QPushButton("按钮3");     QPushButton* btn4 = new QPushButton("按钮4");      //创建网格布局管理器,并添加元素     QGridLayout* layout = new QGridLayout();     layout->addWidget(btn1,0,0);     layout->addWidget(btn2,0,1);     layout->addWidget(btn3,1,0);     layout->addWidget(btn4,1,1);      this->setLayout(layout); }  Widget::~Widget() {     delete ui; }  

//假如是这种布局 //相当于QHBoxLayout layout->addWidget(btn1,0,1); layout->addWidget(btn2,0,2); layout->addWidget(btn3,0,3); layout->addWidget(btn4,0,4); //假如是这种布局 //相当于QVBoxLayout layout->addWidget(btn1, 1, 0); layout->addWidget(btn2, 2, 0); layout->addWidget(btn3, 3, 0); layout->addWidget(btn4, 4, 0);

此处也要注意,设置行和列的时候,如果设置的是一个很大的值,但是这个值和上一个值之间并没有其他的元素,那么并不会在中间腾出额外的空间

假如把btn4设置在第10行,但是由于3-9行没有元素.因此btn4仍然会紧挨在btn3下方,看起来和上面的0 1 2 3的情况是相同的

②设置QGridLayout中元素的大小比例

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");     QPushButton* btn3 = new QPushButton("按钮3");     QPushButton* btn4 = new QPushButton("按钮4");     QPushButton* btn5 = new QPushButton("按钮5");     QPushButton* btn6 = new QPushButton("按钮6");      //创建网络布局管理器,添加元素     QGridLayout* layout = new QGridLayout();     layout->addWidget(btn1,0,0);     layout->addWidget(btn2,0,1);     layout->addWidget(btn3,0,2);     layout->addWidget(btn4,1,0);     layout->addWidget(btn5,1,1);     layout->addWidget(btn6,1,2);      //设置拉伸比例     //第0列拉伸比例为1     layout->setColumnStretch(0,1);     //第1列拉伸比例为0,即为固定大小,不参与拉伸     layout->setColumnStretch(1,0);     //第2列拉伸比例为3,即为第2列的宽度是第0列的3倍     layout->setColumnStretch(2,3);      this->setLayout(layout); }  Widget::~Widget() {     delete ui; }  

另外,QGridLayout也提供了setRowStretch设置行之间的拉伸系数

上述案例中,直接设置setRowStretch效果不明显,因为每个按钮的高度是固定的.需要把按钮的垂直方向的sizePolicy属性设置为QSizePolicy::Expanding尽可能填充满布局管理器,才能看到效果

③设置垂直方向的拉伸系数

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");     QPushButton* btn3 = new QPushButton("按钮3");     QPushButton* btn4 = new QPushButton("按钮4");     QPushButton* btn5 = new QPushButton("按钮5");     QPushButton* btn6 = new QPushButton("按钮6");      //设置按钮的sizePolice,此时按钮的水平和垂直方向都会尽量舒展开     btn1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);     btn2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);     btn3->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);     btn4->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);     btn5->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);     btn6->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);      //创建网络布局管理器,并添加元素     QGridLayout* layout = new QGridLayout();     layout->addWidget(btn1,0,0);     layout->addWidget(btn2,0,1);     layout->addWidget(btn3,1,0);     layout->addWidget(btn4,1,1);     layout->addWidget(btn5,2,0);     layout->addWidget(btn6,2,1);      //设置拉伸比例     //第0行拉伸比例为1     layout->setRowStretch(0,1);     //第1行拉伸比例为0,即为固定大小,不参与拉伸     layout->setRowStretch(1,0);     //第2行拉伸比例为3,即为第2列的宽度是第0列的3倍     layout->setRowStretch(2,3);      this->setLayout(layout);  }  Widget::~Widget() {     delete ui; }  

④表单布局

除了上述的布局管理器之外,Qt还提供了QFormLayout,属于是QGridLayout的特殊情况,专门用于实现两列表单的布局

这种表单布局多用于让用户填写信息的场景.左侧列为提示,右侧列为输入框

#include "widget.h" #include "ui_widget.h" #include #include #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      QFormLayout* layout = new QFormLayout();     this->setLayout(layout);      //创建三个label     QLabel* label1 = new QLabel("姓名");     QLabel* label2 = new QLabel("年龄");     QLabel* label3 = new QLabel("电话");      //创建三个lineEdit     QLineEdit* lineEdit1 = new QLineEdit();     QLineEdit* lineEdit2 = new QLineEdit();     QLineEdit* lineEdit3 = new QLineEdit();      //创建一个提交按钮     QPushButton* btn = new QPushButton("提交");      //把上述元素都添加到layout中     layout->addRow(label1,lineEdit1);     layout->addRow(label2,lineEdit2);     layout->addRow(label3,lineEdit3);     layout->addRow(NULL,btn);  }  Widget::~Widget() {     delete ui; }  

⑤Spacer 在控件之间添加一段空白

属性

说明

width

宽度

height

高度

hData

水平方向的sizePolicy

QSizePolicy::Ignored:忽略控件的尺寸,不对布局产生影响。

QSizePolicy::Minimum:控件的最小尺寸为固定值,布局时不会超过该值。

QSizePolicy:Maximum:控件的最大尺寸为固定值,布局时不会小于该值。

QSizePolicy::Preferred:控件的理想尺寸为固定值,布局时会尽量接近该值。

QSizePolicy::Expanding:控件的尺寸可以根据空间调整,尽可能占据更多空间。

QSizePolicy::Shrinking:控件的尺寸可以根据空间调整,尽可能缩小以适应空间。

vData

垂直方向的sizePolicy

选项同上

①创建一组左右排列的按钮

#include "widget.h" #include "ui_widget.h" #include #include  Widget::Widget(QWidget *parent)     : QWidget(parent)     , ui(new Ui::Widget) {     ui->setupUi(this);      QHBoxLayout* layout = new QHBoxLayout();     this->setLayout(layout);      QPushButton* btn1 = new QPushButton("按钮1");     QPushButton* btn2 = new QPushButton("按钮2");      //创建Spacer     QSpacerItem* spacer = new QSpacerItem(200,20);      layout->addWidget(btn1);      //在两个Widget中间件加上空白     layout->addSpacerItem(spacer);      layout->addWidget(btn2); }  Widget::~Widget() {     delete ui; }  

调整QSpacerltem不同的尺寸,即可看到不同的间距

Qt Designer中,也可以直接给界面上添加spacer

相关内容

热门资讯

一分钟揭秘!透视辅助器(免费)... 网易游戏辅助软件是一款专注玩家量身打造的游戏记牌类型软件,在网易游戏辅助软件这款游戏中我们可以记录下...
玩家必看科普!皮皮衡阳字牌科技... 玩家必看科普!皮皮衡阳字牌科技,新星游辅助怎么购买,原本有开挂辅助安装(确实有挂);打开点击测试直接...
透视透明!新道游房间,微乐小程... 透视透明!新道游房间,微乐小程序辅助脚本平台(扑克教程!开挂辅助神器);打开点击测试直接进入微信(1...
科技介绍!赣牌圈科技有没有挂,... 大家好,今天小编来为大家解答越乡游义乌辅助器微信免费这个问题咨询软件客服可以免费测试直接加微信(13...
来一盘!红茶楼互娱辅助,来趣广... >>您好:红茶楼互娱辅助确实是有挂的,很多玩家在这款红茶楼互娱辅助游戏中打牌都会发现很多用户的牌特别...
透明神器!wepoker透视最... 透明神器!wepoker透视最简单三个步骤,微信微乐辅助器使用教程(曝光教程辅助开挂下载);无需打开...
六分钟了解!杭州都莱可以装挂吗... 蜀山四川智能辅助插件是一款可以让一直输的玩家,快速成为一个“必胜”的ai辅助神器,有需要的用户可以加...
玩家交流!闲来辅助最新版下载,... 闲来辅助最新版下载开挂教程视频分享装挂详细步骤在当今的网络游戏中,闲来辅助最新版下载作为一种经典的娱...
透视规律!微乐小程序免费黑科技... 透视规律!微乐小程序免费黑科技,wepoker能不能透视(攻略方法辅助平台)1、下载安装好微乐小程序...
必知教程!灯笼众娱脚本,潮汕激... 您好:这款灯笼众娱脚本游戏是可以开挂的,确实是有挂的,很多玩家在这款灯笼众娱脚本游戏中打牌都会发现很...