Qt 中的 sizeHint 属性,sizeHint() 如何使用?
Qt 中的 minimumSizeHint 属性,minimumSizeHint() 如何使用?
Qt 中的 sizePolicy 属性,setSizePolicy()、sizePolicy()如何使用?
sizeHint
这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件(为了方便下面统称为widget)的尺寸,也就是说一个 widget 该有多大,它的一个参考来源就是这个 sizeHint 属性的值,而这个值由 sizeHint() 函数来确定。
但是 widget 的大小的确定还有其它因素作用,下面会讲到。现在只需知道 sizeHint() 会返回一个被推荐的尺寸。
那么这个尺寸的取值是怎样的呢?
- 当它是一个无效值的时候,这种情况多半是widget 没有布局(layout),(sizeHint().isValid() 返回 false,QSize 中 width 或者 height 有一个为负数就会是无效的)
- 当它是一个有效值的时候,这种情况就是有布局,它就成了 widget 大小的一个参考。
QWidget *widget = new QWidget;
widget->show();
qDebug() << widget->width() << "," << widget->height();
qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
运行结果:
1009 , 520
-1 , –1
输出结果中第二行:sizeHint() 返回的是一个无效的 QSize,因为 widget 没有布局。
QWidget *widget = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
QPushButton *button = new QPushButton("百度");
layout->addWidget(button);
widget->setLayout(layout);
widget->show();
qDebug() << widget->width() << "," << widget->height();
qDebug() << widget->sizeHint().width() << "," << widget->sizeHint().height();
qDebug() << button->width() << "," << button->height();
运行结果:
112 , 45
97 , 45
90 , 23
输出结果中第一行:widget 的实际尺寸 (112, 45);
输出结果中第二行:sizeHint() 返回 layout 的首选尺寸(97,45)供 widget 参考;
输出结果中第三行:中间 button 的实际大小;
从输出结果中可以证明以上说过的两点:
1) 在 widget 有 layout 的情况下,其 sizeHint() 函数返回的是有效值作为其自身实际尺寸的参考;
2) sizeHint() 返回的值并不一定会作为 widget 的实际尺寸,因为 widget 的尺寸的决定还有其它因素作用;
minimumSizeHint
Qt 中的 widget 有 size 和 minimumSize 两个属性,比较好理解的是上面的 sizeHint 是作为 size 的参考的,那么 minimumSizeHint 是作为 minimumSize 的参考的。minimumSizeHint() 的默认实现同 sizeHint() 基本一样:
在 widget 无 layout 的情况下返回无效值
否则返回 layout 的最小尺寸(minimum size)
注意与上面的首选尺寸不同哦!
有同学会问 preferred size 和 minimum size 的区别:preferred size 由 layout 的 sizeHint() 函数返回,minimum size 由 layout 的 minimumSize() 函数返回;前者的实现会根据 layout 的种类的变化而变化,比如在 QHBoxLayout 和 QVBoxLayout 中各放置同样的两个 QPushButton,两者的 sizeHint() 返回的值是不一样的,后者是返回能够容纳下所有包含在 layout 内的组件的最小尺寸。Qt 中大多数内置的 widget 都已经重新实现了 minimumSizeHint()。你可以自己写自己的 widget 然后重新实现 sizeHint()、minimumSizeHint() 这些函数来达到自己的布局效果。
QWidget *widget = new QWidget;
widget->setMinimumSize(10, 10);
QVBoxLayout *layout = new QVBoxLayout;
QPushButton *button = new QPushButton("百度");
layout->addWidget(button);
widget->setLayout(layout);
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 就可以比之前更小一点啦,
sizePolicy
这个属性保存了该 widget 的默认布局属性,如果它有一个 layout 来布局其子 widgets,那么这个 layout 的 size policy 将被使用;如果该 widget 没有 layout 来布局其子 widgets,那么它的 size policy 将被使用。默认的 policy 是 Preferred/Preferred。
从上图中可以看出 Preferred 虽然可以收缩得比 sizeHint() 更小,但是最小由 minimumSizeHint() 限制
QWidget *widget = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
QPushButton *button = new QPushButton("Ggicci");
//button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addWidget(button);
widget->setLayout(layout);
widget->show();
在第4行代码注释掉的情况下:QPushButton 默认的 sizePolicy 是垂直方向 Fixed,水平方向 Preferred,故水平方向会伸展
QSizePolicy::Preferred 和 QSizePolicy::Expanding 的区别:两者都可以伸展和收缩,但是区别在于谁可以伸展地更牛B
QWidget *widget = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
QPushButton *button1 = new QPushButton("Ggicci");
QPushButton *button2 = new QPushButton("Mingjie Tang");
button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
button2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
layout->addWidget(button1);
layout->addWidget(button2);
widget->setLayout(layout);
widget->show();
两者一样牛B(在水平方向上,垂直方向不构成额外空间竞争关系):
QWidget *widget = new QWidget;
QHBoxLayout *layout = new QHBoxLayout;
QPushButton *button1 = new QPushButton("Ggicci");
QPushButton *button2 = new QPushButton("Mingjie Tang");
button1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->addWidget(button1);
layout->addWidget(button2);
widget->setLayout(layout);
widget->show();
button2更牛B(在水平方向上构成竞争关系)。