第五章布局管理组(Layouts)
文章目录
1.盒子布局(BoxLayout)
c
复制代码
#include "Widget.h"
#include <QBoxLayout>
#include <QCheckBox>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QRadioButton>
Widget::Widget(QWidget* parent)
: QWidget(parent)
{
auto btn1 = new QPushButton("按钮1");
auto btn2 = new QPushButton("按钮2");
auto lab1 = new QLabel;
auto lab2 = new QLabel;
lab1->setPixmap(QPixmap(R"(C:\Users\PVer\Pictures\Resource\松鼠.bmp)")); // 可以使用R"()"令字符串中的内容不进行转义
lab2->setPixmap(QPixmap(R"(C:\Users\PVer\Pictures\Resource\xiaoku.png)"));
auto ledit1 = new QLineEdit;
auto ledit2 = new QLineEdit;
auto boxLayout = new QBoxLayout(QBoxLayout::TopToBottom, this); // 从上到下布局
// boxLayout->addWidget(lab1);
// boxLayout->addWidget(btn1);
// boxLayout->addWidget(ledit1); // 自动添加
// 也可以用子类hboxlayout,vboxlayout布局
auto hbLayout = new QHBoxLayout;
auto vbLayout = new QVBoxLayout;
hbLayout->addWidget(lab1);
hbLayout->addWidget(btn1);
hbLayout->addWidget(ledit1);
vbLayout->addWidget(lab2);
vbLayout->addWidget(ledit2);
boxLayout->addLayout(hbLayout);
boxLayout->addLayout(vbLayout);
boxLayout->addSpacing(50); // 添加固定间距50
hbLayout->addStretch(1); // 设置拉伸因子,像一个弹簧
// 控件也有拉伸因子,默认为0
boxLayout->addWidget(btn2, 2);
boxLayout->setStretchFactor(btn2, 2); // 设置拉伸因子,效果同上
boxLayout->addWidget(btn2, 2, Qt::AlignTop); // 顶部对齐
boxLayout->setDirection(QBoxLayout::LeftToRight); // 修改布局方向
boxLayout->setContentsMargins(10, 20, 30, 40); // 设置边距,左,上,右,下
this->setLayout(boxLayout); // 如果之前layout没指定父对象,也可以通过这个函数指定
}
Widget::~Widget() { }
2.网格布局(GridLayout)
c
复制代码
auto glayout = new QGridLayout(this);
glayout->addWidget(lab1, 0, 0, 2, 2); // 把lab1添加到0行0列,占用2行2列
glayout->addWidget(ledit1, 0, 2); // 不设置占用的话默认占1行1列
glayout->addWidget(ledit2, 1, 2);
glayout->addWidget(btn1, 2, 0, 1, 2); // 占1行2列
// 也可以添加布局
glayout->addLayout(vbLayout, 3, 0); // 整个vblayout只占用1个格子
glayout->setRowStretch(2, 3); // 设置第二行的拉伸因子为3
glayout->setColumnStretch(1, 2); // 第一列的拉伸因子为2
glayout->setColumnMinimumWidth(3, 200); // 设置第三列的最小宽度200
glayout->setRowMinimumHeight(1, 100);
c
复制代码
#include <QFormLayout>
#include <QRadioButton>
QHBoxLayout* sexLayout = new QHBoxLayout;
sexLayout->addWidget(new QRadioButton("男"));
sexLayout->addWidget(new QRadioButton("女"));
auto fLayout = new QFormLayout(this);
fLayout->addRow("姓名", ledit1);
fLayout->addRow("性别", sexLayout);
fLayout->addRow(lab1);
fLayout->setRowWrapPolicy(QFormLayout::WrapAllRows); // 设置换行策略,字段放在标签下、
fLayout->setRowWrapPolicy(QFormLayout::WrapLongRows); // 字段长度不够时换行
fLayout->setSpacing(50); // 设置水平和垂直间距50
fLayout->setWidget(0, QFormLayout::LabelRole, lab2); // 在第0行插入lab2,如果单元格被占用了,则会报错
fLayout->insertRow(0, lab2); // 直接在第0行插入,不会失败
4.堆栈布局(StackedLayout)
c
复制代码
#include <QStackedLayout>
auto sLayout = new QStackedLayout;
// 建3个窗口
QWidget* w1 = new QWidget;
QHBoxLayout* hl = new QHBoxLayout;
hl->addWidget(btn1);
hl->addWidget(ledit1);
w1->setLayout(hl);
QWidget* w2 = new QWidget;
QVBoxLayout* vl = new QVBoxLayout;
vl->addWidget(lab2);
vl->addWidget(btn2);
w2->setLayout(vl);
QWidget* w3 = new QWidget;
QVBoxLayout* vl1 = new QVBoxLayout;
QPushButton* btn3 = new QPushButton("按钮3");
vl1->addWidget(btn3);
w3->setLayout(vl1);
w3->show();
w3->move(10, 10);
sLayout->addWidget(w1);
sLayout->addWidget(w2);
setLayout(sLayout); // 把布局放到主窗口
// 连接按钮切换界面
connect(btn1, &QPushButton::clicked, [=] {
sLayout->setCurrentIndex(1); // 切换到w2
});
connect(btn2, &QPushButton::clicked, [=] {
sLayout->setCurrentIndex(0); // 切换到w1
});
// btn3控制删除和插入界面
connect(btn3, &QPushButton::clicked, [=] {
qInfo() << sLayout->count();
if (sLayout->count() > 1) {
sLayout->removeWidget(w2);
btn3->setText("插入w2");
} else {
sLayout->insertWidget(1, w2);
btn3->setText("删除w2");
}
});
// 布局本身的信号
connect(sLayout, &QStackedLayout::currentChanged, [] { qInfo() << "界面改变了"; });
connect(sLayout, &QStackedLayout::widgetRemoved, [] { qInfo() << "界面被删除了"; });
sLayout->setStackingMode(QStackedLayout::StackAll); // 让所有窗口堆叠显示,后面的窗口在上层
5.分割器(Splitter)
c
复制代码
#include <QSplitter>
#include <QPlainTextEdit>
auto sp = new QSplitter(this);
sp->addWidget(new QPlainTextEdit); // 插入一个多行编辑器
sp->addWidget(new QPlainTextEdit);
sp->insertWidget(2, btn2); // 在2号位置插入btn2
// sp->setOrientation(Qt::Vertical); // 变成垂直分割器
connect(sp, &QSplitter::splitterMoved, [](int pos, int index) {
qInfo() << "当前移动位置=" << pos << "是第几个分割器在移动=" << index;
});
// sp->setChildrenCollapsible(false); // 所有分割器不能移动到控件边缘,控件不能被覆盖
sp->setCollapsible(2, false); // 设置2号分割器不可折叠
c
复制代码
setWindowIcon(QIcon(R"(C:\Users\PVer\Pictures\Resource\xiaoku.png)")); // 设置窗口图标,只有在windows系统有效
setWindowTitle("布局管理器"); // 设置窗口标题
resize(600, 400); // 调整尺寸
setMinimumSize(200, 200); // 设置最小尺寸
btn2->setVisible(false); // 设置控件隐藏
btn2->show();
connect(btn2, &QPushButton::clicked, [=] {
QPixmap pix = this->grab();
pix.save("./pix.jpg");//抓取屏幕截图并保存
});