Qt之手动布局

简述

手动布局,可以实现和水平布局、垂直布局、网格布局等相同的效果,也可实现属于自己的自定义布局,当窗体缩放时,控件可以随之变化。

其对于坐标系的建立有严格要求,纯代码思维,使用复杂,不易维护,所以一般不建议使用。

下面我们以简单的例子来讲解如何使用。

  • 简述
  • 事件
  • 垂直布局
    • 简略图
    • 效果
    • 源码
  • 水平布局
    • 效果
    • 源码
  • 总结

事件

Qt之布局管理器一节中,我们介绍了对于手动布局的实现思路。

通过QWidget::resizeEvent()来计算所需要分配的大小,并且给每个子控件调用setGeometry()。

垂直布局

简略图

我们先简单看一个简略图,是一个一个垂直布局的界面,包含各个部位的组成以及大小限制。

其中Left Margin、Top Margin、Right Margin、Bottom Margin分别指各个控件距离窗体的左、上、右、下外边距,Spacing指控件之间的间距。

效果

源码

void MainWindow::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    int nSpacing = 10;
    int nLeft = 10;
    int nTop = 10;
    int nRight = 10;
    int nBottom = 10;

    // 标签位置、大小
    m_pLabel->setGeometry(nLeft, nTop, width() - nLeft - nRight, 20);

    // 按钮大小
    m_pButton->setFixedSize(75, 25);

    // 设置按钮位置
    m_pButton->move(width() - m_pButton->width() - nRight, height() - nBottom - m_pButton->height());

    // 中央窗体位置、大小
    m_pCentralWidget->setGeometry(nLeft, nTop + nSpacing + m_pLabel->height(),
                                  width() - nLeft - nRight, height() - nTop - 2 *nSpacing - m_pLabel->height() - m_pButton->height() - nBottom);
}

标签和中央窗体的宽度均为:width() - nLeft - nRight,即:窗体宽度 - 左边距 - 右边距。

标签的坐标为QPoint(nLeft, nTop),即:x为左边距,y为上边距。

中央窗体的坐标为:QPoint(nLeft, nTop + nSpacing + m_pLabel->height()),即:x:左边距,y:上边距 + 间距 + 标签高度。

中央窗体的高度为:height() - nTop - 2 nSpacing - m_pLabel->height() - m_pButton->height() - nBottom。即:窗体高度 - 上边距 - 标签高度 - 按钮高度 - 下边距 - 2 间距。

按钮大小为:QSize(75, 25),即:width:75,height:25。

按钮位置:QPoint(width() - m_pButton->width() - nRight, height() - nBottom - m_pButton->height())。即:x:窗体宽度 - 按钮宽度 - 右边距,y:窗体高度 - 按钮高度 - 下边距。

水平布局

实现思路不再过多讲解,参考垂直布局。

效果

源码

void MainWindow::resizeEvent(QResizeEvent *event)
{
    QWidget::resizeEvent(event);

    int nSpacing = 10;
    int nLeft = 10;
    int nTop = 10;
    int nRight = 10;
    int nBottom = 10;

    m_pLeftButton->setFixedSize(75, 25);
    m_pCentralButton->setFixedSize(75, 25);
    m_pRightButton->setFixedSize(75, 25);

    // 居左
    //m_pLeftButton->move(nLeft, nTop);
    //m_pCentralButton->move(nLeft + m_pLeftButton->width() + nSpacing, nTop);
    //m_pRightButton->move(nLeft + m_pLeftButton->width() + m_pCentralButton->width() + 2 * nSpacing, nTop);

    // 居右
    m_pRightButton->move(width() - m_pRightButton->width() - nRight, nTop);
    m_pCentralButton->move(width() - m_pCentralButton->width() - m_pRightButton->width() - nSpacing - nRight, nTop);
    m_pLeftButton->move(width() - m_pLeftButton->width() - m_pCentralButton->width() - m_pRightButton->width() - 2 * nSpacing - nRight, nTop);
}

总结

好了,关于网格布局或其他复杂布局就不再一一介绍了,主要计算好各个控件的相对坐标即可。

有人肯定会有疑惑,为什么不使用setGeometry(10, 10, 100, 75),而必须通过resizeEvent()来计算坐标呢?

主要区别:

  • setGeometry(10, 10, 100, 75)采用绝对坐标和位置,适用于窗体大小固定的情况。一旦大小发生变化,则无计可施。
  • resizeEvent()计算坐标属于相对位置,无论窗体如何变化,都可以适应其在窗体中的布局。
时间: 2024-09-18 04:06:14

Qt之手动布局的相关文章

qt中格子布局删除布局中的控件,行数未减少

问题描述 qt中格子布局删除布局中的控件,行数未减少 //原先这个格子布局中有4个按钮,现在删除第一个的按钮,在最后以后添加一个按钮. QLayoutItem* pDeleteItem(NULL); pDeleteItem = m_pGridLayout->itemAt(0); if(pDeleteItem != NULL) { QWidget* pWidget = pDeleteItem->widget(); m_pGridLayout->removeWidget(pWidget);

qt c++-QT使用中关于布局与信号与槽的基础问题,求高手来看看

问题描述 QT使用中关于布局与信号与槽的基础问题,求高手来看看 1.假如在一个QDialog中左边是一个QTreeWidget右边添加一个Qwidget空间,QWidget里面放4个QLabel,用GridLayout布局平分,现在实现双击某一个label,其余3个label隐藏,而只有一个label出现并且填充满整个Qwidget,怎么实现这个过程? 2.在一个QT的button槽函数里,实现对视频文件回放:打开文件解码(解码产生一个getImage(QImage*)信号),然后由这个信号关联

Qt之自定义布局管理器(QCardLayout)

简述 手动布局另一种方法是通过继承QLayout类编写自己的布局管理器. 下面我们详细来举一个例子-QCardLayout.它由同名的Java布局管理器启发而来.也被称之为卡片布局,每个项目偏移QLayout::spacing(). 简述 定义 实现 效果 源码 定义 编写自己的布局,必须定义如下: 一种存储布局处理项目的数据结构,每个项目都是一个QLayoutItem,本例使用QList. addItem() 如何添加项目布局. setGeometry() 如何控制布局. sizeHint()

Qt之格栅布局(QGridLayout)

简述 QGridLayout:格栅布局,也被称作网格布局(多行多列). 栅格布局将位于其中的窗口部件放入一个网状的栅格之中.QGridLayout需要将提供给它的空间划分成的行和列,并把每个窗口部件插入并管理到正确的单元格. 栅格布局是这样工作的: 它计算了位于其中的空间,然后将它们合理的划分成若干个行(row)和列(column),并把每个由它管理的窗口部件放置在合适的单元之中,这里所指的单元(cell)即是指由行和列交叉所划分出来的空间. 在栅格布局中,行和列本质上是相同的,只是叫法不同而已

Qt之自定义布局管理器(QFlowLayout)

简述 QFlowLayout,顾名思义-流布局,实现了处理不同窗口大小的布局.根据应用窗口的宽度来进行控件放置的变化. 具体实现要求不再赘述,请参考前两节内容. 简述 实现 效果 源码 实现 QFlowLayout主要采用QLayout和QWidgetItem实现,而窗口使用了QWidget和QPushButton. 效果 源码 QFlowLayout.h #ifndef QFLOWLAYOUT_H #define QFLOWLAYOUT_H #include <QLayout> #inclu

Qt之自定义布局管理器(QBorderLayout)

简述 QBorderLayout,顾名思义-边框布局,实现了排列子控件包围中央区域的布局. 具体实现要求不再赘述,请参考前几节内容. 简述 实现 效果 源码 使用 实现 QBorderLayout主要采用QLayout和QWidgetItem实现,而窗口使用了QWidget,中央窗体使用QTextBrowser,四周以QLabel排列. 效果 源码 QBorderLayout.h #ifndef QBORDERLAYOUT_H #define QBORDERLAYOUT_H #include <

《Qt 实战一二三》

简介 "我们来自Qt分享&&交流,我们来自Qt Quick分享&&交流",不管你是笑了,还是笑了,反正我们是认真的.我们就是要找寻一种Hold不住的状态,来开始每一天的点滴分享,我们是一个有激情,有态度的部队. 但是我们还是我们,我们只是多了一份责任.古语有云:"不积跬步无以至千里,不积小流无以成江海",所以每一个伟大事务的产生都不是一蹴而就的.现在我们要立足眼下,把第一站放在地球,"<Qt 实战一二三>&quo

Qt之布局管理器

简述 Qt的布局系统提供了一个简单的和强有力的方式,来自动排列窗口子控件布局. 所有QWidget子类可以使用布局来管理他们的子控件.QWidget::setLayout()函数可以为一个控件布局.当通过这种方式布局以后,它负责以下任务: 布置子控件. 最高层窗口可感知的默认大小. 最高层窗口可感知的最小大小. 调整大小的处理. 当内容改变的时候自动更新: 字体大小.文本或者子控件的其它内容. 隐藏或者显示子控件. 移除一些子控件. 简述 Qt的布局类 水平垂直网格表单布局 代码布局 为布局添加

Qt 学习之路 2 --- 读书笔记

一.文章来由 来自豆子老师非常好的一本Qt教程,但是只有网络版,所以用这个做笔记了,不动笔墨不读书嘛~~ 二.读书笔记 1.Qt 学习之路 2(2):Qt 简介 1.1 关于 Qt 的一站式解决 Qt 是一个著名的 C++ 应用程序框架.但并不只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI 组件.使用 Qt,在一定程度上你获得的是一个"一站式"的解决方案:不再需要研究 STL,不再需要 C++ 的,不再需要到处去找解析 XML.连接数据库.访问网络的各种第三方库,因为