分享

Qt的5种常用布局搭建...

 wuxinit_ 2021-03-31

Qt——中心窗口setCentralWidget

http://blog.csdn.net/qter_wd007/article/details/7028920

Qt程序中的主窗口通常具有一个中心窗口部件。从理论上来讲,任何继承自QWidget的类的派生类的实例,都可以作为中心窗口部件使用。

代码中动态添加中心部件示例(可实现将this这个窗体中所有控件占满全屏的效果)

   QWidget* cWidget=new QWidget();
   cWidget->setLayout(ui->gridLayout);
   this->setCentralWidget(cWidget);//相当于选中this这个窗体,在菜单栏中选栅格布局类型的效果
  • 几种常见情形

QMainWindow的中心区域可以被任意种类的窗口部件所占用。下面给出的是可能的情形。

⒈ 使用标准的Qt窗口部件(Standard Widget)

像QWidget、Qlabel以及QTextEdit等等这样的标准窗口部件都可以用作中心窗口部件。

⒉ 使用自定义窗口部件(User-Define-Widget)

            有时候,某些有特殊要求的应用程序需要在自定义窗口部件中显示数据,你可以把自定义的窗口部件作为中心窗口部件。例如,你的绘图编辑器程序程序就可以使用类似名为PhotoEditor的自定义窗口部件作为自己的中心窗口部件。

3. 使用一个带布局管理器的普通Widget

            有时候,应用程序的中央区域会被许多窗口部件所占用。这时就可以通过使用一个作为所有这些其他窗口部件父对象的QWidget,以及通过使用布局管理器管理这些子窗口部件的大小和位置来完成这一特殊情况。

4. 使用切分窗口(QSplitter)

            其实,这种情况是上一种情况的一个例子。多个窗口部件一起使用的另一种方法是使用QSplitter。我们把QSplitter作为一个容器,在其中容纳其它的窗口部件,这时的中心窗口部件就是一个QSplitter。QSplitter会在水平方向或者竖直方向上排列它的子窗口部件,用户可以利用切分条(splitter handle)控制他们的尺寸大小。切分窗口可以包含所有类型的窗口部件,包括其他切分窗口。

5. 使用多文档界面工作空间(QMdiArea)

            如果应用程序使用的是多文档界面,那么它的中心区域就会被QMdiArea窗口部件所占据,并且每个多文档界面窗口都是它的一个子窗口界面。QMdiArea是在Qt4.3以后引入的一个支持多文档应用的类。

6. 使用工作空间部件(QWorkspace)

            这种情况通常用于多文档应用程序中,这时应用程序主窗口的中心部件是一个QWorkspace部件或者它的子类化部件。但这种方法在Qt4.5以后将被废弃。后面我们还会讲到它。

  • 创建和使用

            一个Qt主窗口应用程序必须有一个中心窗口部件(Central Widget)。当你采用Qt Designer创建主窗口时,默认情况下,系统已经为你创建了一个中心窗口部件,它是子类化QWidget的。

            结合代码可以方便的设置中心窗口部件,可以调用主窗口类的setCentralWidget()方法,它的原型如下:

void QMainWindow::setCentralWidget ( QWidget * widget )
 
它将把widget设置为主窗口的中心窗口部件。

创建中心窗口部件完整的代码示例如下:

QTextEdit * text;
text = new QTextEdit(this);
setCentralWidget(text);

            Qt应用程序的主窗口管理着中心窗口部件,它会在合适的时候销毁这个中心窗口部件。每次程序调用setCentralWidget()方法时,先前存在的中心窗口部件将被新的所替换,而且主窗口会销毁原来的部件,无需用户处理。

            要想在程序中获得并使用、设置中心窗口部件也很简单,通过调用主窗口类的centralWidget()方法即可实现,它的函数原型如下:

QWidget * QMainWindow::centralWidget () const

它将返回主窗口的中心窗口部件,如果中心窗口部件不存在,它将返回0。一个完整的示例代码如下:

QTextEdit * text = centralWidget();
//设置属性,但通常不需要
..

QT设置centralWidget布局

设置之前是这样的,这时候即使设置了控件的布局,实际上控件大小还是不会跟这变,因为centralWidget没有设置布局。
这里写图片描述
需要在没有控件的空白区域,点击右键在布局中选择一种布局:
这里写图片描述
布局后, centralWidget有布局了,这时候控件就能正常跟随窗口缩放了。
这里写图片描述

 

Qt布局详解:

 

界面开发首先要对整个界面进行布局,使窗体上的所有的控件必须有一个合适的尺寸和位置。那么做出来的界面才看起来美观。

那么如何对界面进行布局呢?Qt提供了一些类负责排列窗体上的控件,主要有:QHBoxLayout,QVBoxLayout,QGridLayout,QFormLayout,QStackLayout。(布局管理类)这些类简单易用,无论在代码中还是用Qt Designer开发程序都能用到。

      常用的布局方法:

(1)使用水平布局类QHBoxLayout;

(2)使用垂直布局类QVBoxLayout;

(3)使用网格布局类QGridLayout;

(4)使用表格布局类QFormLayout;

(5)使用分组布局类QStackLayout(  QStackedLayout类把子控件进行分组或者分页,一次只显示一组或者一页,隐藏其他组或者页上的控件)。

这些方法可以嵌套使用。使用这些Qt布局管理类的另一个原因是,在程序、系统改变字体,语言或者在不同的平台上运行时,布局管理器能够自动调整窗体里所有控件的大小和尺寸。

布局管理的三种方式:

Qt中有三种方式对窗体上的控件进行布局管理:

1.绝对位置定位(absolute positioning):控件布局是固定位置,没有自适应功能。

例子如下:

QWidget *pWidget = new QWidget;

QLabel label(pWidget);

label.setText(QObject::tr("姓名:"));

label.setGeometry(10,10,20,20);

 QLineEdit namedLineEdit("小王",pWidget);

namedLineEdit.setGeometry(35,10,50,20);

 QPushButton *btn = new QPushButton(QObject::tr("关闭"),pWidget);

     btn->setGeometry(90,10,40,20);

                             

2.手工布局(manual layout):给出控件的绝对位置,但是他们的尺寸根据窗口的大小确定,可以通过重写窗体控件的resizeEvent()实现对子控件的大小设置。

 

3.布局管理器(layout managers):运用QHBoxLayout、QVBoxLayout、QGridLayout 、QFormLayout、QStackLayout布局。

 

(1).Horizontal Layout布局设置(水平布局):他包含的对象都横向排列开,示例如图3-1所示:

                                         

 

                                             图 3-1  水平布局

(2).Vertical Layout布局设置(垂直布局):他包含的对象都纵向排列开,示例如图3-2所示:

                                                      

                                                 图3-2  竖直布局

 

(3).Grid Layout布局设置(网格布局):将控件放置到网格中布局,它本身会从父窗口或父布局中占据尽可能多的界面空间,然后把自己的空间划分为行和列,再把每个控件塞到设置好的一个或多个单元格中。通常情况下 QGridLayout不需要自己添加空白条 QSpacerItem,因为其他功能控件把各自的单元格占据之后,剩下没控件占据的单元格自然就是空的,空的格子默认里面什么都没有,也没有空白条。示例如图3-3所示:

                               

                                                  图3-3 网格布局

(4).Form Layout布局设置(表格布局):专门用于管理输入控件和与之相关的标签等表单布局,QFormLayout固定为两列布局,并针对表单做了建模,配套了一堆方便使用的函数。网格布局器的基本单元是单元格,而表单布局器的基本单元是行。表单布局器是高度建模并封装的,它没有 addWidget()和 addLayout()之类的函数,它只有addRow()函数。表单布局器中一行的空间可以由多个控件占据,也可以由一个控件占据。示例如图3-4所示:

                                        

                                                    图3-4 表格布局

(5).布局管理器在指定的位置留出一块空间:(Qt Designer中,可以加入一个spacer实现这一功能)示例如图3-5所示:

                                   

                                                 图3-5  布局留出指定空间

(6).QSpliter分割器的作用:分裂器 QSplitter 是一个实体功能控件,它的基类是 QFrame,QFrame 基类正是 QWidget。QSplitter 可以独立存在,可以作为父窗口容纳多个子控件,分裂器会完全拥有内部的子控件。在 Qt 设计师或 QtCreator 设计模式左边 Widget Box 里面没有分裂器可以拖动,使用分裂器的方式是:选中已有的控件,然后点击上面工具栏的水平分裂器或垂直分裂器按钮。比如上图是将三个丰富文本编辑器作为一个水平分裂器排布 的。分裂器内每个控件都有一个手柄 Handle,水平分裂器内控件的手柄在左边,垂直分裂器内控件的手柄在控件上方。第 0 个控件的手柄是永久隐藏的,分裂器自身占据的大矩形四个边界线通常不能拖动拉大,只能拖动控件之间的手柄,比如上图的手柄 1 和 手柄 2 。分裂器整体的尺寸不是用户控制的,而在分裂器内部的控件尺寸可以让用户手工拖动手柄来控制。在程序运行时,水平分裂器内各个控件的宽度、垂直分裂器内部各个控件的高度, 一般都是用户拖动手柄控制,这是分裂器和布局器最大的不同。

具体操作如下图3-6所示:

                           

                                                               图  3-6

实际效果如下图3-7所示:

                                           

                                                     图 3-7分割实际效果图

 

 

 

sizepolicy:

1. Fixed: 大小不能改变

2. Minimum: 已经是最小, 不能再被缩小, 但能放大.

3. Maximum: 已经是最大, 不能再被放大, 但能缩小.

4. Preferred:  控件的sizeHint()是他的sizeHint, 能被缩小, 放大.

5. Expanding: 控件可以自行增大或者缩小.


 

设置部件大小

只要是继承自QWidget的类都有以下两个属性:

大小提示:siziHint() 保存部件的建议大小信息 ->通过函数可获取

最小大小提示:minimumSizeHint() 保存部件的建议最小大小信息 ->通过函数可获取

sizePolicy属性:

常量描述
QSizePolicy::Fixed只能使用sizeHint()提供的值,无法伸缩
QSizePolicy::MinimumsiziHint()提供的大小是最小的,部件可以被拉伸
QSizePolicy::MaximumsizeHint()提供的是最大大小,部件可以被压缩
QSizePolicy::PreferredsizeHint()提供的大小是最佳大小,可以拉伸可以压缩
QSizePolicy::ExpandingsizeHint()提供的是合适的大小,部件可以被压缩,不过更倾向于拉伸来获得更多的空间
QSizePolicy::MinimumExpandingsizeHint()提供的大小是最小的,部件倾向于被拉伸来获取更多的空间
QSizePolicy::IgnoredsizeHint()的值被忽略,部件将尽可能的被拉伸来获取更多的空间

关于伸缩因子(stretch factor)的概念:在代码中,可以在使用布局管理器的addWidget()函数添加部件时,在第二个参数指定伸缩因子。2,1

 

QLayout

属性说明
layoutName现在所使用的布局管理器的名称
layoutLeftMargin设置布局管理器到界面左边界的距离
layoutTopMargin设置布局管理器到界面上边界的距离
layoutRightMargin右边界
layoutBottomMargin下边界
layoutSpacing布局管理器各个子部件间的距离
layoutStretch伸缩因子
layoutSizeConstraint设置大小约束条件

QT窗口尺寸,窗口大小和大小改变引起的事件 QResizeEvent。

来源: http://www./bbs/apps.php?q=diary&a=detail&did=1277&uid=139581

 

 

 


来源:http://blog.csdn.net/dbzhang800/article/details/6741344?reload
操作:


frameGeometry()


几何尺寸(位置+大小)


对于窗口,包含窗口装饰器


x()y()pos()


只包含位置信息(左上角坐标)


move()


只移动位置


geometry()


几何尺寸(位置+大小)


不包含窗口装饰器


width()height()rect()size()


只包含大小信息


setGeometry()


改变位置+大小


resize()


只改变大小



一直在考虑怎么使中心窗口在主窗口全屏之后,中心窗口也按比例放大。
其中包括,中心窗口的大小适应,中心窗口
1.创建你的UI,其中使用弄好你的顶级布局,选中widget窗口 - 点击右键 - 布局 - 栅格布局。

2.构造函数中

复制代码

  1.   centralWidget = new QWidget;
       QWidget * a = new QWidget(centralWidget);
       ui1->setupUI(a);
         a->hide();
       QWidget * b = new QWidget(centralWidget);
       ui2->setupUI(b);
         b->hide();
       setCentralWidget(centralWidget) //这样的好处在于,你可以弄很多ui,想使用哪个UI直接uin->setupUI(widgetn),再widgetn->show()就可以了。



3.但是如果你想拖动主窗口的时候,能够让窗口中的组件随着窗口也能缩放的话,需要重写resizeEvent,原因在于,在构造之后,子窗口的大小就是固定的。

复制代码

  1. void resizeEvent(QresizeEvent* size){
        centralWidget->resize(frameGeometry().size()); //是采用size()还是frameGeometry.size()根据自己的需求。
    }



有什么问题,请留言说明,大家一起交流并且解决。

附加设备相关的屏幕尺寸信息,如果你重写resizeEvent的话,我认为这是不必要的。
QDesktopWidget* desktopWidget = QApplication::desktop();
//得到客户区矩形
QRect clientRect = desktopWidget->availableGeometry();
//得到应用程序矩形
QRect applicationRect = desktopWidget->screenGeometry();

 

QT 栅格布局(Grid Layout),设置控件所占行数(rowSpan)和所占列数(columnSpan)

QT的栅格布局(Grid Layout)划分了行和列,能够将控件放入一个网状的栅格之中显示,每个控件能够占一格或多行多列,例如:

但是如果先拖入一个Grid Layout,再添加控件是没办法设置控件所占行列的,要用其他的办法才可以。

控件占任意行列的布局方法:

方法一:

1.先将控件的位置摆好如图:

2.全选控件,点上方的栅格布局,控件的位置就自动设置好了。

3.要追加控件,先选中gridlayout,点击打破布局

再添加控件并摆放好位置,全选重新点栅格布局就行了

方法二:

代码的方式添加,有点繁琐

void addWidget(QWidget *, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0);
这个单元将从row和column开始,扩展到rowSpan和columnSpan指定的倍数的行和列。如果rowSpan或columnSpan的值为-1,则窗口部件将扩展到布局的底部或者右边边缘处。

在创建栅格布局完成后,就可以使用addWidget(),addItem(),以及addLayout()方法向其中加入窗口部件,以及其它的布局。

例子:

 
  1. QWidget *widget;

  2. QGridLayout *gridLayout;

  3. QPlainTextEdit *plainTextEdit;

  4. QPushButton *pushButton;

  5. QPushButton *pushButton_2;

  6. QProgressBar *progressBar;

  7. //gridLayout

  8. widget = new QWidget(ui.centralWidget);

  9. widget->setObjectName(QString::fromUtf8("widget"));

  10. widget->setGeometry(QRect(90, 40, 339, 99));

  11. gridLayout = new QGridLayout(widget);

  12. gridLayout->setSpacing(6);

  13. gridLayout->setContentsMargins(11, 11, 11, 11);

  14. gridLayout->setObjectName(QString::fromUtf8("gridLayout"));

  15. gridLayout->setContentsMargins(0, 0, 0, 0);

  16. //文本框

  17. plainTextEdit = new QPlainTextEdit(widget);

  18. plainTextEdit->setObjectName(QString::fromUtf8("plainTextEdit"));

  19. gridLayout->addWidget(plainTextEdit, 0, 0, 2, 1);

  20. //按钮1

  21. pushButton = new QPushButton(widget);

  22. pushButton->setObjectName(QString::fromUtf8("pushButton"));

  23. pushButton->setText(QStringLiteral("btn1"));

  24. gridLayout->addWidget(pushButton, 0, 1, 1, 1);

  25. //按钮2

  26. pushButton_2 = new QPushButton(widget);

  27. pushButton_2->setObjectName(QString::fromUtf8("pushButton_2"));

  28. pushButton_2->setText(QStringLiteral("btn2"));

  29. gridLayout->addWidget(pushButton_2, 1, 1, 1, 1);

  30. //进度条

  31. progressBar = new QProgressBar(widget);

  32. progressBar->setObjectName(QString::fromUtf8("progressBar"));

  33. progressBar->setValue(24);

  34. gridLayout->addWidget(progressBar, 2, 0, 1, 2);

效果:

Qt 让弹出的窗口居中显示

设置窗口居中显示这是在UI编程中经常要遇到的问题。

方法一:在窗口(QWidget类及派生类)的构造函数中添加如下代码:

#include <QDesktopWidget>

//.......
QDesktopWidget* desktop = QApplication::desktop(); // =qApp->desktop();也可以
move((desktop->width() - this->width())/2, (desktop->height() - this->height())/2);
//.......

重新编译后,该窗口启动时在屏幕居中的位置。

方法二:在调用show()函数后调用move()函数,j将窗口移动到屏幕中央。

#include <QDesktopWidget>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    w.move ((QApplication::desktop()->width() - w.width())/2,(QApplication::desktop()->height() - w.height())/2);
    return a.exec();

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多