Qt中的 Size Hints 和 Size Policies
Qt 中的 sizeHint 属性,sizeHint() 如何使用? Qt 中的 minimumSizeHint 属性,minimumSizeHint() 如何使用?Qt 中的 sizePolicy 属性,setSizePolicy()、sizePolicy()如何使用?
之前一直对这几个属性搞不清楚,前几天仔仔细细地看了文档解释并做了一些测试,现在来归纳一下:
首先我们得知道这几个属性保存的值是什么,它们分别是用来干什么的。
sizeHint [From Qt Doc: This property holds the recommended size for the widget. If the value of this property is an invalid size, no size is recommended. The default implementation of sizeHint() returns an invalid size if there is no layout for this widget, and returns the layout's preferred size otherwise. ] 这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件(为了方便下面统称为widget)的尺寸,也就是说一个 widget 该有多大,它的一个参考来源就是这个 sizeHint 属性的值,而这个值由 sizeHint() 函数来确定。但是 widget 的大小的确定还有其它因素作用,下面会讲到。现在只需知道 sizeHint() 会返回一个被推荐的尺寸。那么这个尺寸的取值是怎样的呢?当它是一个无效值的时候(sizeHint().isValid() 返回 false,QSize 中 width 或者 height 有一个为复数就会是无效的),什么作用也没有;当它是一个有效值的时候,它就成了 widget 大小的一个参考。Qt 中对 sizeHint() 的默认实现是这样的:当 widget 没有布局(layout),返回无效值;否则返回其 layout 的首选尺寸(preferred size)。1: QWidget *widget = new QWidget;
2: widget->show();
3: qDebug() << widget->width() << "," << widget->height();
4: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
1: //output:
2: //1009 , 520
3: //-1 , –1输出结果中第二行:sizeHint() 返回的是一个无效的 QSize,因为 widget 没有布局。
1: QWidget *widget = new QWidget;
2: QHBoxLayout *layout = new QHBoxLayout;
3: QPushButton *button = new QPushButton("Ggicci");
4: layout->addWidget(button);
5: widget->setLayout(layout);
6: widget->show();
7: qDebug() << widget->width() << "," << widget->height();
8: qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
9: qDebug() << button->width() << "," << button->height();
1: //output:
2: //112 , 45
3: //97 , 45
4: //90 , 23输出结果中第一行:widget 的实际尺寸 (112, 45);输出结果中第二行:sizeHint() 返回 layout 的首选尺寸(97,45)供 widget 参考;输出结果中第三行:中间 button 的实际大小;从输出结果中可以证明以上说过的两点:
1) 在 widget 有 layout 的情况下,其 sizeHint() 函数返回的是有效值作为其自身实际尺寸的参考;2) sizeHint() 返回的值并不一定会作为 widget 的实际尺寸,因为 widget 的尺寸的决定还有其它因素作用;
1: QWidget *widget = new QWidget;
2: widget->setMinimumSize(10, 10);
3: QVBoxLayout *layout = new QVBoxLayout;
4: QPushButton *button = new QPushButton("Ggicci");
5: layout->addWidget(button);
6: widget->setLayout(layout);
7: widget->show();这里同上显示一个含有 QPushButton 的 QWidget,不过在这里设置了其最小尺寸为(10, 10),此时 minimumSizeHint() 将不起作用,也就是我们可以把 widget 缩放到(10, 10),不过这是理论上的哦,亲~(在这里你讲看到一个例外),以下就是缩小到了极致:(112,10),同学,是否在思考为什么 width 无法缩小到比 112 更小了。其实这是 widget 和 windows 系统的共同问题,第一 widget 默认有 min,max,close 三个按钮,也就是右上角的最小化、最大化、关闭按钮,这导致了 width 无法继续缩小。其实通过 widget->setWindowFlags(Qt::Window | Qt::WindowTitleHint); 可以把 min, max 按钮给去了,这样的 widget 的 width 就可以比之前更小一点啦,如下右图。
Constants
Description
QSizePolicy::Fixedwidget 的实际尺寸只参考 sizeHint() 的返回值,不能伸展(grow)和收缩(shrink)QSizePolicy::Minimum可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸QSizePolicy::Maximum可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能伸展到的最大尺寸QSizePolicy::Preferred可以伸展和收缩,但没有优势去获取更大的额外空间使自己的尺寸比 sizeHint() 的返回值更大QSizePolicy::Expanding可以伸展和收缩,它会尽可能多地去获取额外的空间,也就是比 Preferred 更具优势QSizePolicy::MinimumExpanding可以伸展和收缩,不过sizeHint() 的返回值规定了 widget 能缩小到的最小尺寸,同时它比 Preferred 更具优势去获取额外空间QSizePolicy::Ignored忽略 sizeHint() 的作用
从上图中可以看出 Preferred 虽然可以收缩得比 sizeHint() 更小,但是最小由 minimumSizeHint() 限制
QSizePolicy::Fixed1: QWidget *widget = new QWidget;
2: QHBoxLayout *layout = new QHBoxLayout;
3: QPushButton *button = new QPushButton("Ggicci");
4: //button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
5: layout->addWidget(button);
6: widget->setLayout(layout);
7: widget->show();在第4行代码注释掉的情况下:QPushButton 默认的 sizePolicy 是垂直方向 Fixed,水平方向 Preferred,故水平方向会伸展没有注释掉的情况下: QSizePolicy::Preferred 和 QSizePolicy::Expanding 的区别:两者都可以伸展和收缩,但是区别在于谁可以伸展地更牛B
1: QWidget *widget = new QWidget;
2: QHBoxLayout *layout = new QHBoxLayout;
3: QPushButton *button1 = new QPushButton("Ggicci");
4: QPushButton *button2 = new QPushButton("Mingjie Tang");
5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
6: button2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
7: layout->addWidget(button1);
8: layout->addWidget(button2);
9: widget->setLayout(layout);
10: widget->show();两者一样牛B(在水平方向上,垂直方向不构成额外空间竞争关系):
1: QWidget *widget = new QWidget;
2: QHBoxLayout *layout = new QHBoxLayout;
3: QPushButton *button1 = new QPushButton("Ggicci");
4: QPushButton *button2 = new QPushButton("Mingjie Tang");
5: button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
6: button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
7: layout->addWidget(button1);
8: layout->addWidget(button2);
9: widget->setLayout(layout);
10: widget->show();button2更牛B(在水平方向上构成竞争关系):有了上述的样例,QSizePolicy::Minimum, QSizePolicy::Maximum, QSizePolicy::MinimumExpanding, QSizePolicy::Ignored 就比较好理解了吧,亲