布局管理 ######################################## 设置部件尺寸 [#]_ **************************************** Qt部件的尺寸与两个属性有关:`尺寸提示(sizeHint)` 和 `尺寸策略(sizePolicy)`,其中: - sizeHint 代表了建议大小 - sidePolicy 根据其取值对部件做出改变,其取值如下: .. csv-table:: sidePolicy取值 :header: 常量, 描述 QSizePolicy::Fixed, sizeHint()提供的是固定值,部件无法被拉伸或压缩 QSizePolicy::Minimum, sizeHint()提供的是最小值,部件只能被拉伸 QSizePolicy::Maximum, sizeHint()提供的是最大值,部件只能被压缩 QSizePolicy::Preferred, sizeHint()提供的是最佳大小,部件可以被拉伸或压缩 QSizePolicy::Expanding, sizeHint()提供的是合适的大小,部件可以被压缩,但是更希望被拉伸 QSizePolicy::MinimumExpanding, sizeHint()提供的是最小值,部件倾向于被拉伸 QSizePolicy::Ignored, sizeHint()提供的值被忽略,部件将尽可能获取更多的空间 .. [#] Qt Creator快速入门(第三版) 4.1.2 设置部件大小 布局管理器 **************************************** 布局管理器的继承关系如下: .. image:: assets/QLayout.png 伸缩因子 ======================================== 继承自 ``QBoxLayout`` 的 ``setStretchFactor()`` 函数家族可以用于设置布局管理器内部件之间的比例。例如: .. code-block:: cpp QHBoxLayout* hlayout = new QHBoxLayout(this); QPushButton* btn1 = new QPushButton(this); QPushButton* btn2 = new QPushButton(this); centwidget->setLayout(hlayout); hlayout->addWidget(btn1); hlayout->addWidget(btn2); hlayout->setStretchFactor(btn1, 1); hlayout->setStretchFactor(btn2, 2); 表现形式如下: .. image:: assets/setStretchFactor.png 自定义布局 **************************************** 在某些情况下,你可能会发现在第二次向容器中加入小部件的时候小部件会重叠在一起。原因是添加小部件时默认是不会调用 *setGeometry* 的。一个简单的办法就是在 *addItem* 时调用一次 *update* 。当然,为了效率着想,你可以需要 *延迟刷新* 。 .. code-block:: cpp FlowLayout::FlowLayout(QWidget* parent) : QLayout(parent){ // 延迟刷新 timer_->setInterval(300); connect(timer_, &QTimer::timeout, this, &FlowLayout::update); } void FlowLayout::addItem(QLayoutItem* item) { list_.append(item); // 这里不 update 的话,没有 resize 之前,item 是叠在一起的 timer_->start(); } QScrollArea **************************************** QScrollArea 根据 QScrollArea::setWidget(QWidget* w) 。中的 w 来决定是否显示滚动条,其不会缩放内部部件的尺寸。当 w 的尺寸比 QScrollArea 大的时候,会显示滚动条。w的尺寸由你自己设置。 因此如果想要部件的宽度跟着 QScrollArea 变,高度自由变,最简单的方法就是事件过滤器 .. code-block:: cpp bool eventFilter(QObject* watched, QEvent* event) { if(event->type() == QEvent::Resize) { w->resize(real_width, real_height); return true; } return false; }