Qt布局管理(2):大小约束(主窗口最大最小大小的设置)
本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)
本文出自本人原创著作《Qt5.10 GUI完全参考手册》网盘地址:
https://pan.baidu.com/s/1iqagt4SEC8PUYx6t3ku39Q
《C++语法详解》网盘地址:https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg
若对C++语法不熟悉,建议参阅本人所著《C++语法详解》一书,电子工业出版社出版,该书语法示例短小精悍,对查阅C++知识点相当方便,并对语法原理进行了透彻、深入详细的讲解,可确保读者彻底弄懂C++的原理,彻底解惑C++,使其知其然更知其所以然。此书是一本全面了解C++不可多得的案头必备图书。
此处的主窗口是指安装布局管理器的部件。当显示设置了主窗口的最小大小后,即使子部件大小策略为Fixed也能对部件进行压缩,但若不设置主窗口的最小大小,若子部件大小策略为Fixed,则部件不会拉伸(示例略,读者可自行验证)。
大小约束是由属性QLayout::sizeConstraint进行描述的,大小约束其实就是用来设置主窗口的最大和最小值的,该属性原型如下:
sizeConstraint:SizeConstraint //注意大小写字母S,QLayout类的属性 SizeConstraint枚举见表5-2
访问函数:sizeConstraint sizeConstraint() const; void setSizeConstraint(SizeConstraint);
示例5.4:大小约束(用于设置主窗口最大最小大小)
//m.h文件的内容
#ifndef M_H
#define M_H
#include<QtWidgets>
#include<QDebug>
#include <iostream>
using namespace std;
class B:public QPushButton{ Q_OBJECT
public: QWidget* pw; QLayout *pl; //创建两个数据成员用于传递数据
B(QString s="",QWidget* p=0):QPushButton(s,p){}
public slots:
void f(){
pw=parentWidget(); //获取当前按钮的父部件
pl=pw->layout(); //获取父部件的布局管理器,layout()是QWidget类中的函数
QString t=text(); //获取当前按钮显示的文本
if(t=="Default") //如果按下的是Default按钮
{ pl->setSizeConstraint(QLayout::SetDefaultConstraint);} //设置大小约束
if(t=="Fixed"){ pl->setSizeConstraint(QLayout::SetFixedSize); }
if(t=="Maxi"){pl->setSizeConstraint(QLayout::SetMaximumSize);}
if(t=="MinAndMax"){ pl->setSizeConstraint(QLayout::SetMinAndMaxSize);}
if(t=="NoCon") {pl->setSizeConstraint(QLayout::SetNoConstraint);}
if(t=="CusMin"){pw->setMinimumSize(22,22); } //手动设置主窗口的最小值
pl->activate(); //重新设置主窗口的布局,此函数必须调用,否则主窗口的数据不会立即更新
g(); } //调用函数g显示当前父部件的最大/最小值
void g(){ //用于输出当前父部件的最大最小值。
cout<<"minW="<<pw->minimumSize().width()<<",";
cout<<"minH="<<pw->minimumSize().height()<<",";
cout<<"maxW="<<pw->maximumSize().width()<<",";
cout<<"maxH="<<pw->maximumSize().height()<<endl; } };
#endif // M_H
//m.cpp文件的内容
#include "m.h"
int main(int argc, char *argv[]){ QApplication a(argc,argv);
QWidget w; B *pb,*pb1,*pb2,*pb3,*pb4,*pb5; QHBoxLayout *pg;
pb=new B("Default"); pb1=new B("Fixed"); pb2=new B("Maxi");
pb3=new B("MinAndMax"); pb4=new B("NoCon"); pb5=new B("CusMin");
//设置各子部件的大小策略
pb->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
pb1->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
pb2->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
pb3->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
pb4->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
pb5->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
//把子部件添加到布局中
pg=new QHBoxLayout; pg->addWidget(pb); pg->addWidget(pb1); pg->addWidget(pb2);
pg->addWidget(pb3); pg->addWidget(pb4); pg->addWidget(pb5); w.setLayout(pg);
//关联信号和槽
QObject::connect(pb, &QPushButton::clicked, pb, &B::f);
QObject::connect(pb1, &QPushButton::clicked, pb1, &B::f);
QObject::connect(pb2, &QPushButton::clicked, pb2, &B::f);
QObject::connect(pb3, &QPushButton::clicked, pb3, &B::f);
QObject::connect(pb4, &QPushButton::clicked, pb4, &B::f);
QObject::connect(pb5, &QPushButton::clicked, pb5, &B::f);
w.resize(300,100); w.show(); return a.exec(); }
运行结果(见图5-9、5-10,5-11)及说明
按以下顺序点击按钮:
①、点击Default按钮后,输出为:minW=502, minH=45, maxW=16777215, maxH=16777215,这是SetDefaultConstraint约束设置的主窗口的最大/最小值,其中最大值未设置(16777215是最初的默认值未被改变),最小值被设置为(502,45),此时主窗口可拉伸,但不可压缩得比最小值小
②、点击Fixed按钮后,输出为:minW=502,minH=45,maxW=502,maxH=45,可见SetFixedSize约束把主窗口的最大/最小值都设置为了(502,45),此时主窗口大小不可更改(因为最大最小值相等),其效果如图5-10所示
③、点击Maxi按钮后,输出:minW=502,minH=45,maxW=524287,maxH=45,可见SetMaximumSize约束把最大值设置为了(524284,45),但是最小值未被重新设置。此时主窗口可水平拉伸,但不能垂直拉伸,因为垂直方向最大最小值相等
④、点击NoCon输出的是上次设置的大小,也就是说SetNoConstraint约束未对主窗口的最大最小值进行设置,主窗口保持上次设置的值。主窗口仍可进行水平拉伸不可进行垂直拉伸
⑤、点击CusMin手动改变主窗口的最小值,输出minW=22, minH=22, maxW=524287, maxH=45,此时主窗口可水平拉伸和压缩,但不能进行垂直拉伸和压缩。其效果如图5-11所示
⑥、再次点击NoCon按钮,验证SetNoConstraint约束是保持上次设置的值,此时输出的是上次设置的大小minW=22,minH=22,maxW=524287,maxH=45。
⑦、再次点击Default按钮,验证SetDefaultConstraint约束不会再次对最大最小值进行设置,此时输出的是上次设置的大小minW=22,minH=22,maxW=524287,maxH=45。
⑧、验证SetMaximumSize约束只会设置最大值而不会设置最小值,步骤如下
点击Fixed按钮,此时主窗口大小更改为(502,45,502,45),再点击CusMin按钮,主窗口大小被更改为(22,22,502,45),接着点击Maxi按钮,输出minW=22, minH=22, maxW=524287, maxH=45
⑨、其余规则读者可自行验证
总结:大小约束与大小策略的关系
大小约束是用来改变主窗口最大最小大小的,主窗口的最大最小大小决定了主窗口是否可进行拉伸或压缩,而子部件(比如本例的按钮)是否可被拉伸和压缩是由各子部件的大小策略决定的,因此大小约束和大小策略一个决定主窗口是否可拉伸压缩,一个决定了子部件是否可拉伸压缩。
系统计算主窗口的最大最小大小时会根据子部件的大小策略进行计算,比如例5.4的子部件在垂直方向的大小策略为Fixed(即固定不变),则主窗口依此计算出来的在垂直方向的最大和最小高度始终为45,而水平方向各子部件的大小策略是Expanding(可拉伸),因此主窗口在水平方向计算出来的最大大小可以为524287,读者可把例5.4子部件垂直方向的大小策略更改为Expanding,再点击以上按钮来观察主窗口在垂直方向的最大最小值有何变化。
本文作者:黄邦勇帅(原名:黄勇)