QT。向 QLayout 添加新布局

Posted

技术标签:

【中文标题】QT。向 QLayout 添加新布局【英文标题】:QT. Add new layout to QLayout 【发布时间】:2016-04-28 15:28:19 【问题描述】:

我在应用程序运行时动态创建接口。

1) 我有带有 4 个预定义选项卡的 QTabWidget。但我必须只显示 1 或 2 个选项卡,以防用户选择。在 *** 上我了解到,我必须将所有选项卡保存在集合中才能添加和销毁它。

我有 QHash:twInputMethodsTabs = new QHash< int, QPair<QWidget*, QString> >();

第一个参数 = 索引;第二 = 选项卡小部件;第三 = 选项卡小部件标题文本;

2) 我这样填充集合:

for(int i = 0; i < ui->twInputMethods->children().length(); i++)
    
        twInputMethodsTabs->insert(i, QPair<QWidget*, QString>(ui->twInputMethods->widget(i), ui->twInputMethods->tabText(i)));
    

3) 我在标签中添加新的小部件,如下所示:

twInputMethodsTabs-&gt;value(1).first-&gt;layout()-&gt;addWidget(cmbbCommands);

4) 我如何向这个小部件添加新布局?我想这样做:

QHBoxLayout *hblParams  =new QHBoxLayout();
twInputMethodsTabs->value(1).first->layout()->addLayout(hblParams);

但它不起作用,因为layout() 返回QLayout 而没有addLayout() 函数。我该怎么做?

或者我应该如何改变代码架构来做到这一点?

【问题讨论】:

布局只能应用于 QWidgets。您要做的就是插入一个小部件并将新布局应用到该小部件。 标签小部件可以包含布局以对齐其中的所有项目。在上面的示例中,我在此布局上添加了小部件 - 它工作正常。现在,我想添加几个小部件,一一对齐。我认为是这样的:TabWidget (has Layout(has widget, Layout(has widget, widget)))。更清楚? @gek0n 是什么让您认为“选项卡小部件可以包含布局以对齐其中的所有项目。”?无法将布局应用于选项卡(因为它不是QWidget)。你可以做的是创建一个容器QWidget 来保存你的布局和相关的小部件。然后将此容器添加到选项卡。 @mfitzp 你是什么意思?一个选项卡实际上是一个 QWidget:QTabWidget::addTab(QWidget *page, const QString &amp;label) @gek0n 选项卡的内容是否在执行期间动态变化?如果不只是在开始时创建所有内容并且不要使用您存储在哈希中的小部件。否则,如果您确定之前在小部件中放置的布局,您可以将 twInputMethodsTabs-&gt;value(1).first-&gt;layout() 转换为实际布局并使用 addLayout。 【参考方案1】:

在以下代码中,您将获得一个小部件 (.first),然后选择该小部件的布局 -&gt;layout(),然后将一个小部件添加到该布局 -&gt;addWidget()

twInputMethodsTabs->value(1).first->layout()->addWidget(cmbbCommands);

在下面的代码中,您将获得一个小部件 (.first),然后选择该小部件的布局 -&gt;layout() 并尝试在布局上设置布局。

twInputMethodsTabs->value(1).first->layout()->addLayout(hblParams);

替换 QLayout

要在父窗口小部件上设置布局,您需要删除-&gt;layout()

twInputMethodsTabs->value(1).first->addLayout(hblParams);

请注意,由于您现在正在向小部件添加一个空布局,因此之前布局中的任何当前小部件都将丢失,因此您可能需要将小部件重新添加到布局中。

在现有的 QLayout 中添加新的 QLayout

如果您想将布局添加到现有布局中,则无法直接执行此操作。 QLayout 只能通过.addWidget() 接受QWidget。但是,您可以将布局应用到空的 QWidget(),然后将 that 添加到布局中。例如:

QWidget *w = new QWidget();
w.addLayout(hblParams);
twInputMethodsTabs->value(1).first->layout()->addWidget(w);

另一种方法是将QWidget 上的布局设置为支持.addLayout() 的布局,例如QHBoxLayoutQVBoxLayout。例如:

QVBoxLayout *l = new QVBoxLayout();
cmbbCommands.setLayout(l);  // Now has a layout that supports .addLayout
twInputMethodsTabs->value(1).first->layout()->addWidget(cmbbCommands);

现在下面应该可以工作了,因为-&gt;layout() 返回一个QVBoxLayout

QHBoxLayout *hblParams  =new QHBoxLayout();
twInputMethodsTabs->value(1).first->layout()->addLayout(hblParams);

【讨论】:

不不不。这不是我想要的。我不想用新布局替换旧布局。我想在旧布局内添加新布局。就像一个小部件。我需要这样做以在选项卡小部件的布局中对其他小部件进行分组。 @gekon 那么你需要在你的问题中说明这一点。对于它的价值“不不不”。与试图帮助您的人交谈是一种粗鲁的方式。 这只是一种不好的情绪,因为我不能说清楚的英语。行。当我为 MainWindow 选择 V​​erticalLayout 时。我添加到 MainWindow Horizo​​ntalLayout 和 3 个按钮。然后我将另一个 Horizo​​ntalLayout 和 3 InputText 添加到 MainWindow 中。它工作正常。但我不知道如何在 tabwidget 中做同样的事情 好的。我认为这只是一种方法 - 就像你的描述 @gek0n 可能还有其他方法(请参阅更新)。如果您将布局设置为 QVBoxLayout()(或任何其他支持 .addLayout() 的布局类型,则 -&gt;layout() 调用将返回此类型,并且您的原始代码应该可以工作。【参考方案2】:

我希望,我得到你想要做的:

twInputMethodsTabs->value(1).first->layout()->addWidget(cmbbCommands);

QHBoxLayout *hblParams  =new QHBoxLayout();
QWidget *w = new QWidget(twInputMethodsTabs->value(1).first);
twInputMethodsTabs->value(1).first->layout()->addWidget(w);

w->addLayout(hblParams);

我只是在这里写了代码,所以它是未经测试的。但是,它应该让您了解我在评论中试图解释的内容。

【讨论】:

我认为这是不好的方式。某处有好方法。为什么我可以向QT Designer 中的任何小部件添加任意数量的布局,但不能以编程方式执行相同的技巧? 在设计器中,布局小部件只是一个已应用布局的 QWidget。这正是您以编程方式执行此操作的方式,是什么让您认为这是一种不好的方式?也许你可以解释一下,你的意思是什么。 不,我无法解释。我只是不知道它在设计师中的表现如何,所以我不能说那是好是坏。所以我认为“也许有更多的好方法”。但正如你所说 - 这是唯一的一条真路。谢谢【参考方案3】:

从“工作”应用程序中删除:

  WidgetA::WidgetA(QWidget *parent) : QWidget(parent)
  
      QVBoxLayout *pLayout = new QVBoxLayout();
      buildWidget(pLayout);
      this->setLayout(pLayout);
  

void WidgetA::buildWidget(QVBoxLayout *layout)
  for(int i=0; i<4; ++i)
       this->buildSegments(layout);
  


void WidgetA::buildSegments(QVBoxLayout *layout)
    QHBoxLayout *pHbl = new QHBoxLayout();
    QLabel *pSegmentSize = new QLabel(this);
    pSegmentSize->setText(tr("Segment Size(1,N)"));
    QSpinBox *pSegments = new QSpinBox(this);
    pHbl->addWidget(pSegmentSize);
    pHbl->addWidget(pSegments);
    layout->addItem(pHbl);
   

阅读这篇文章:Widgets Tutorial - Nested Layouts

【讨论】:

以上是关于QT。向 QLayout 添加新布局的主要内容,如果未能解决你的问题,请参考以下文章

缺少 QLayout 构造函数来实现卡片布局

Qt学习笔记3.布局

尝试将 QLayout“”添加到已经有布局的 convertidorNumericoDialogo“”[重复]

类QLayout和类QMainWindow Qt c++之间的继承

Qt之自定义布局管理器(QCardLayout)

QT自定义布局示例有关Overlappig小工具无法编译