Qt第五章布局管理

第五章布局管理组(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);

3.表单布局(FormLayout)

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号分割器不可折叠

QWidget补充

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");//抓取屏幕截图并保存
    });
相关推荐
Momo__1 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富1 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇1 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇1 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆1 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马1 小时前
Verilog开发常见问题汇总解析
前端
子兮曰1 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端
weedsfly1 小时前
语法糖褪去之后——Babel 转译产物中的 JavaScript 本貌
前端·javascript
JustHappy2 小时前
「软件设计思想杂谈🤔」“切图仔”也能懂编译原理?框架源码也许没那么难。聊聊 Vue 的编译(上)
前端·javascript·vue.js