布局管理
设置部件尺寸[1]
Qt部件的尺寸与两个属性有关:尺寸提示(sizeHint)
和 尺寸策略(sizePolicy),其中:
sizeHint 代表了建议大小
-
- sidePolicy 根据其取值对部件做出改变,其取值如下:
.sidePolicy取值 [cols=",",options="header",] |=== |常量 |描述 |QSizePolicy::Fixed |sizeHint()提供的是固定值,部件无法被拉伸或压缩
|QSizePolicy::Minimum |sizeHint()提供的是最小值,部件只能被拉伸
|QSizePolicy::Maximum |sizeHint()提供的是最大值,部件只能被压缩
|QSizePolicy::Preferred |sizeHint()提供的是最佳大小,部件可以被拉伸或压缩
|QSizePolicy::Expanding |sizeHint()提供的是合适的大小,部件可以被压缩,但是更希望被拉伸
|QSizePolicy::MinimumExpanding |sizeHint()提供的是最小值,部件倾向于被拉伸
|QSizePolicy::Ignored |sizeHint()提供的值被忽略,部件将尽可能获取更多的空间 |===
布局管理器
布局管理器的继承关系如下:
伸缩因子
继承自 QBoxLayout
的 setStretchFactor()
函数家族可以用于设置布局管理器内部件之间的比例。例如:
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);
表现形式如下:
自定义布局
在某些情况下,你可能会发现在第二次向容器中加入小部件的时候小部件会重叠在一起。原因是添加小部件时默认是不会调用 setGeometry 的。一个简单的办法就是在 addItem 时调用一次 update 。当然,为了效率着想,你可以需要 延迟刷新 。
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 变,高度自由变,最简单的方法就是事件过滤器
bool eventFilter(QObject* watched, QEvent* event) {
if(event->type() == QEvent::Resize) {
w->resize(real_width, real_height);
return true;
}
return false;
}
坐标转换
Qt 有两个基本函数用于转换坐标:mapToGlobal 和 mapToParent
第一个函数用来将本地坐标映射到全局坐标。等价于 pWidget→globalPos()+QPoint(x,y)
第二个函数用来将本地坐标映射到父坐标
mapFromGlobal 和 mapFromParent 亦如此了