【问题标题】:How to position an added widget to a layout based on another widget in the same layout?如何根据同一布局中的另一个小部件将添加的小部件定位到布局?
【发布时间】:2016-04-20 14:27:03
【问题描述】:

在我的 GUI 中,我想根据特定操作触发的信号以编程方式将 QComboBox 添加到 verticalLayout。以下代码工作正常并添加了小部件:

QComboBox* userOptions = new QComboBox();
ui->verticalLayout_13->addWidget(userOptions);

但是,这种方式总是将小部件添加到布局的末尾。

我的问题是:如何将添加的QComboBox 定位到verticalLayout 以与同一布局中的另一个小部件对齐? (例如:在“Go”按钮上方)

【问题讨论】:

  • 你真的需要创建一个新的 QComboBox 吗?因为你可以让它在布局中并设置它是否可见,无论你是否需要它。
  • @YMoreau:我只是按照您的建议使用了可见性属性。谢谢

标签: c++ qt qcombobox


【解决方案1】:

似乎没有办法在您想要的布局中显式插入项目。

你有几个选择来实现“硬”的方式:

  • 使用QLayout::takeAt(int index) 获取您要插入的索引之后的所有项目,插入您的项目,然后插入回已获取的项目。
  • 创建一个占位符小部件,您可以使用它在布局中保留索引,然后您不会在布局中插入项目,而是在嵌套在占位符小部件内的布局中插入。如果没有项目,占位符小部件不会占用空间,并且会扩展以容纳放入其中的任何内容。
  • 实现您自己的QLayout 子类,它支持在特定索引处插入。您必须实现几个功能。

编辑:正如 Kuba Ober 指出的那样,我的遗漏是,大多数具体布局实现都支持在特定索引处插入,例如 QBoxLayout 派生具有将索引作为参数传递的插入方法。

【讨论】:

  • 这看起来像是很多不必要的“艰苦”工作,因为我认为这将是一项很好且容易学习的技能。就我的应用程序而言,我将坚持回答中的第一行(至少目前如此),并按照“Y Moreau”的建议使用可见性属性。谢谢
  • 您可能想再次查看具体布局的文档。是的,仅使用QLayout 接口是无法做到的,但所有具体布局都绝对支持它。 QGridLayout 不允许您直接插入,但您可以轻松地洗牌现有项目,为新项目腾出空间。
  • @KubaOber - 是的,这是真的,我以前没有注意到,主要是因为我没有太多使用布局,而且大部分时间 - 在静态场景中。我主要使用 QML,而 QML 布局根本没有。
  • 在 QML 中,如果您不使用布局,则 IIRC 也可以重新绑定位置以动态更改视觉布局。
【解决方案2】:

首先,迭代布局以找到您插入的参考项的相对索引。然后使用具体布局的特定小部件插入/添加功能。

由于您可能使用QBoxLayout,因此您将使用其insertWidget 方法插入小部件。

// https://github.com/KubaO/stackoverflown/tree/master/questions/insert-widget-36746949
#include <QtWidgets>

namespace SO { enum InsertPosition { InsertBefore, InsertAfter }; }

bool insertWidget(QBoxLayout * layout, QWidget * reference, QWidget * widget,
                  SO::InsertPosition pos = SO::InsertBefore, int stretch = 0,
                  Qt::Alignment alignment = 0) {
   int index = -1;
   for (int i = 0; i < layout->count(); ++i)
      if (layout->itemAt(i)->widget() == reference) {
         index = i;
         break;
      }
   if (index < 0) return false;
   if (pos == SO::InsertAfter) index++;
   layout->insertWidget(index, widget, stretch, alignment);
   return true;
}

可以为QFormLayoutQGridLayoutQStackedLayout 轻松设计类似的功能。

还有一个测试工具:

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   QWidget w;
   QVBoxLayout l{&w};
   QLabel first{"First"};
   QLabel second{"Second"};
   l.addWidget(&first);
   l.addWidget(&second);
   insertWidget(&l, &first, new QLabel{"Before First"}, SO::InsertBefore);
   insertWidget(&l, &second, new QLabel{"After Second"}, SO::InsertAfter);
   w.show();
   return app.exec();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-20
    • 2017-05-24
    • 2013-05-01
    • 2012-06-03
    • 1970-01-01
    相关资源
    最近更新 更多