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-11-07 18:20:39

Qt之手动布局的相关文章

qt坐标系统与布局的简单入门

 qt坐标系统 qt坐标系统比較简单 button.setGeometry(20,20,100,100); 上面的代码把button显示为父窗体的20,20处宽度为100,高度为100 接下去是布局 qt里面布局须要增加<QLayout.h>这个头文件. qt里面垂直布局 qt里面的垂直布局须要导入<QVBoxLayout.h>这个头文件. qt里面的水平布局须要导入<QHBoxLayout.h>这个头文件. 以下是是一段布局的代码 QHBoxLayout layo

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

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

qt——常用的布局方法

布局相关对象及简介 窗体上的所有的控件必须有一个合适的尺寸和位置.Qt提供了一些类负责排列窗体上的控件,主要有:QHBoxLayout,QVBoxLayout,QGridLayout,QStackLayout.(布局管理类)这些类简单易用,无论在代码中还是用Qt Designer开发程序都能用到. 1)         布局类简介 QHBoxLayout:水平布局 QVBoxLayout:垂直布局 QGridLayout: 表格布局 QGridLayout::addWidget()语法 layo

QT的组件布局

在QT的IDE下,编写一个自定义布局. 1 #include<QApplication> 2 #include<QWidget> 3 #include<QSpinBox> 4 #include<QSlider> 5 #include<QHBoxLayout> 6 7 int main (int argc,char *argv[]) 8 { 9 QApplication app(argc, argv); 10 QWidget * window =

Qt学习四 - 布局管理器

开发界面程序,一定会涉及到布局的问题.我们需要让控件显示在理想中的位置,可以直接设置控件的坐标和宽高.但是这样带来一个问题,当用户改变窗口大小时,例如点击最大化按钮或者拖拽窗口边缘,控件是不会改变的(包括控件的坐标和宽高).因为在窗口改变时,你没有告诉程序是否更新控件以及如何更新.如果需要让控件自动更新,那么就要自己来写一些函数来相应这些变化.针对这种情况,Qt提供了一种机制 - 布局,来解决这个问题(大部分用于开发界面程序的语言或者框架,都会提供类似的机制).只需要将控件放入某一种布局,当位置

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之格栅布局(QGridLayout)

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

Qt系列04 布局管理

本节介绍Qt常用布局管理,QSplitter类.QDockWidget类和QStackedWidget类. QSplitter类 #include "widget.h" #include <QApplication> #include <QSplitter> #include <QLineEdit> int main(int argc, char *argv[]) { QApplication a(argc, argv); QSplitter *sp