我有一个 Qt 窗口,窗口底部是一行小部件(主要是按钮和复选框)供用户交互。
我希望那行小部件看起来很漂亮(其中“漂亮”对我来说被定义为“均匀间隔”——也就是说,无论用户为其窗口选择什么宽度,这一行中的小部件应该始终具有它们之间以及最左边和最右边的小部件与窗口边缘之间的空间相等)。
即该行应如下所示(其中 XXX 表示小部件):
[ XXX XXX XXX XXX XXX XXX ]
这看起来很容易做到——也就是说,我可以做这样的事情:
QBoxLayout * hbl = new QBoxLayout(Qt::LeftToRight, parentWidget);
hbl->addStretch();
hbl->addWidget(new QPushButton);
hbl->addStretch();
hbl->addWidget(new QPushButton);
hbl->addStretch();
hbl->addWidget(new QPushButton);
[...]
hbl->addStretch();
只要所有小部件都可见,就可以工作。
问题是有时我想隐藏行中的一些小部件,因为它们与手头的任务无关。
在这种情况下,剩余可见的小部件最终会分布不均匀,因为无法隐藏与现在隐藏的按钮关联的“拉伸(stretch)”项目。
例如,如果我要隐藏上面显示的行中的第一个和第二个小部件,那么其余的小部件最终看起来像这样:
[ XXX XXX XXX XXX ]
^^^^^^ ^^
too much space on the left!
是否有一种简单的方法来获得我想要的行为,或者我是否需要深入研究显式处理隐式 QSpacerItems?
最佳答案
解决方案
由于QBoxLayout
不支持更改QLayoutItem
的可见性,我建议您执行以下操作:
使用
QLayout::takeAt
删除并删除隐藏的小部件左侧的拉伸(stretch)部分。像这样:delete hbl->takeAt(ind - 1);
使用
QBoxLayout::insertStretch
在显示的小部件的左侧插入一个新的拉伸(stretch)。像这样:hbl->insertStretch(ind);
ind
是隐藏/显示的小部件的布局索引。
示例
这是我为您准备的一个最小示例,用于演示建议的解决方案:
#include <QMainWindow>
#include <QBoxLayout>
#include <QPushButton>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr) :
QMainWindow(parent)
{
auto *widget = new QWidget(this);
auto *hbl = new QHBoxLayout(widget);
auto *btnLeft = new QPushButton(("Button"), widget);
auto *btnRight = new QPushButton("Hide/Show", widget);
hbl->addStretch();
hbl->addWidget(btnLeft);
hbl->addStretch();
hbl->addWidget(new QPushButton("Unused", this));
hbl->addStretch();
hbl->addWidget(btnRight);
hbl->addStretch();
connect(btnRight, &QPushButton::clicked, [hbl, btnLeft](){
int ind = 0;
btnLeft->setVisible(!btnLeft->isVisible());
for (int n = 0; n < hbl->count(); n++) {
auto *w = hbl->itemAt(n)->widget();
if (w && w == btnLeft)
ind = n;
}
if (btnLeft->isVisible())
hbl->insertStretch(ind);
else
delete hbl->takeAt(ind - 1);
});
setCentralWidget(widget);
resize(800, 600);
}
};
关于c++ - 如何轻松地展开一排 Qt 小部件,使它们始终均匀分布?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52597506/