Qt 从布局中获取子元素

发布于 2024-09-30 04:47:50 字数 403 浏览 10 评论 0原文

我尝试隐藏布局中的所有小部件。但看起来 findChildren 没有 进行布局工作。

这是我的示例代码:

QLayout * layout = widget -> findChild<QLayout *> (layoutName);
QList<QWidget *> list = layout -> findChildren<QWidget *> ();

cout << list.size() << endl;

size 是 0,但在这个布局中我有一些小部件。 但如果我尝试从父小部件获取小部件,相同的代码可以正常工作。

我如何才能从适当的布局中获得它们?

I try to hide all widgets in layout. But looks like findChildren doesn't
work for layout.

Here's my sample code:

QLayout * layout = widget -> findChild<QLayout *> (layoutName);
QList<QWidget *> list = layout -> findChildren<QWidget *> ();

cout << list.size() << endl;

size is 0, but inside this layout I have a few widgets.
But the same code works fine if I try to get widgets from parent widget.

How I can get them from appropriate layout?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

本宫微胖 2024-10-07 04:47:51

已经很晚了,但如果有人像我一样找到这里,这是我的解决方案:
我尝试了@braggPeaks 答案(与@Frank Osterfeld 答案相同),但失败了。然后我像这样修改,它就像一个魅力。 (我不知道它为什么有效,因为我的布局没有空项目,但我仍然必须检查它是否有。)

for (int i = 0; i < this->layout->count(); ++i) {
    QWidget *w = this->layout->itemAt(i)->widget();
    if(w != NULL)
        w->setVisible(false);
}

It's very late but if anyone finds here like me, here is my solution:
I tried @braggPeaks answer(it's same as @Frank Osterfeld answer) but it failed. Then I modified like this and it works like a charm. (I have no idea why it works, because my layout has no null items but still I have to check if it has.)

for (int i = 0; i < this->layout->count(); ++i) {
    QWidget *w = this->layout->itemAt(i)->widget();
    if(w != NULL)
        w->setVisible(false);
}
挽心 2024-10-07 04:47:51

由于布局不是小部件层次结构的一部分,因此必须从父部件查询小部件,但可以使用 indexOf 来查看它是否属于及其位置

  QLayout * top_l= layout(); // The parent widgets layout
   // Find your layout that you want to search inside
   QHBoxLayout * hbox = top_l->findChild<QHBoxLayout*>(QString("horizontalLayout_2"));
    if (hbox != 0) {
        std::cout << "Found horizontalLayout_2!"<<std::endl;
        QPushButton * st = findChild<QPushButton*>(QString("startButton"));

        if (st != 0) {
            std::cout << "Found startButton in top level widget"<<std::endl;
            int idx = hbox->indexOf(st);
            if (idx >=0) {
                std::cout << "Found startButton in hbox layout at location : "
                          <<idx<<std::endl;
            }
        }
    };

Since layout is not part of widget hierarchy, the widget has to be queried from parent but then indexOf can be used to see if it belongs and its location

  QLayout * top_l= layout(); // The parent widgets layout
   // Find your layout that you want to search inside
   QHBoxLayout * hbox = top_l->findChild<QHBoxLayout*>(QString("horizontalLayout_2"));
    if (hbox != 0) {
        std::cout << "Found horizontalLayout_2!"<<std::endl;
        QPushButton * st = findChild<QPushButton*>(QString("startButton"));

        if (st != 0) {
            std::cout << "Found startButton in top level widget"<<std::endl;
            int idx = hbox->indexOf(st);
            if (idx >=0) {
                std::cout << "Found startButton in hbox layout at location : "
                          <<idx<<std::endl;
            }
        }
    };
£冰雨忧蓝° 2024-10-07 04:47:51

回复旧帖子,但我想要一种简单的方法来禁用布局或任何子布局中包含的所有小部件。这符合我的目的:

void setEnabledWidgetsInLayout(QLayout *layout, bool enabled)
{
   if (layout == NULL)
      return;

   QWidget *pw = layout->parentWidget();
   if (pw == NULL)
      return;

   foreach(QWidget *w, pw->findChildren<QWidget*>())
   {
      if (isChildWidgetOfAnyLayout(layout,w))
         w->setEnabled(enabled);
   }
}

bool isChildWidgetOfAnyLayout(QLayout *layout, QWidget *widget)
{
   if (layout == NULL or widget == NULL)
      return false;

   if (layout->indexOf(widget) >= 0)
      return true;

   foreach(QObject *o, layout->children())
   {
      if (isChildWidgetOfAnyLayout((QLayout*)o,widget))
         return true;
   }

   return false;
}

Responding to an old post, but I wanted a simple way to disable all widgets contained in a layout or any child-layout. This worked for my purposes:

void setEnabledWidgetsInLayout(QLayout *layout, bool enabled)
{
   if (layout == NULL)
      return;

   QWidget *pw = layout->parentWidget();
   if (pw == NULL)
      return;

   foreach(QWidget *w, pw->findChildren<QWidget*>())
   {
      if (isChildWidgetOfAnyLayout(layout,w))
         w->setEnabled(enabled);
   }
}

bool isChildWidgetOfAnyLayout(QLayout *layout, QWidget *widget)
{
   if (layout == NULL or widget == NULL)
      return false;

   if (layout->indexOf(widget) >= 0)
      return true;

   foreach(QObject *o, layout->children())
   {
      if (isChildWidgetOfAnyLayout((QLayout*)o,widget))
         return true;
   }

   return false;
}
挽袖吟 2024-10-07 04:47:51

我认为创建一个 QWidget 作为容器并将您的小部件放入该“容器小部件”中更容易,这样您可以通过在“容器小部件”上调用 findChildren 来访问您的小部件:

auto children = ui->containerWidget->findChildren<QWidget *>();
for (auto child : children) {
    child->setVisible(false);
}

I think it is easier to create a QWidget as a container and put your widgets inside of that "container widget", this way you could access your widgets by calling findChildren on the "container widget":

auto children = ui->containerWidget->findChildren<QWidget *>();
for (auto child : children) {
    child->setVisible(false);
}
最好是你 2024-10-07 04:47:51

您是否尝试过 children() 方法而不是 findChildren() ?也许您从 widget -> 中得到了“糟糕”的布局。 findChild; (layoutName) 方法。尝试在创建布局后立即找到子项 - 这样您就可以确定布局是正确的。这样做您将能够确定哪个功能出现问题。

Did you try children() method instead of findChildren() ? Maybe you are getting a 'bad' layout from widget -> findChild<QLayout *> (layoutName) method. Try to find children right after creating the layout - so you are sure the layout is correct. Doing so you will be able do determine what function works wrong.

喵星人汪星人 2024-10-07 04:47:50

布局不会将自身“注入”到父子树中,因此小部件保留其父小部件的(直接)子代。

您可以使用 QLayout::count()QLayout::itemAt() 来代替。

The layout does not "inject" itself in the parent-child tree, so the widgets stay (direct) children of their parent widget.

You could use QLayout::count() and QLayout::itemAt() instead.

九局 2024-10-07 04:47:50

您可以使用 itemAt() 简单地迭代布局的项目,然后测试该项目是否是小部件:

for (int i = 0; i < gridLayout->count(); ++i)
{
  QWidget *widget = gridLayout->itemAt(i)->widget();
  if (widget != NULL)
  {
    widget->setVisible(false);
  }
  else
  {
    // You may want to recurse, or perform different actions on layouts.
    // See gridLayout->itemAt(i)->layout()
  }
}

You can simply iterate over the layout's items, using itemAt(), then test whether the item is a widget:

for (int i = 0; i < gridLayout->count(); ++i)
{
  QWidget *widget = gridLayout->itemAt(i)->widget();
  if (widget != NULL)
  {
    widget->setVisible(false);
  }
  else
  {
    // You may want to recurse, or perform different actions on layouts.
    // See gridLayout->itemAt(i)->layout()
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文