C++ Qt从布局中获取子对象

C++ Qt从布局中获取子对象,c++,qt,qt4,qt-designer,C++,Qt,Qt4,Qt Designer,我试图隐藏布局中的所有小部件。但是看起来findChildren没有 为布局工作 以下是我的示例代码: QLayout * layout = widget -> findChild<QLayout *> (layoutName); QList<QWidget *> list = layout -> findChildren<QWidget *> (); cout << list.size() << endl; QLayo

我试图隐藏布局中的所有小部件。但是看起来
findChildren
没有 为布局工作

以下是我的示例代码:

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

cout << list.size() << endl;
QLayout*layout=widget->findChild(layoutName);
QList=layout->findChildren();
您是否尝试了
children()
方法而不是
findChildren()
?也许你从
widget->findChild(layoutName)
方法中得到了一个“糟糕”的布局。尝试在创建布局后立即查找子级-以便确保布局正确。这样做,您将能够确定哪些功能工作不正常。

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


您可以使用
QLayout::count()
QLayout::itemAt()

由于布局不是小部件层次结构的一部分,因此必须从父级查询小部件,然后可以使用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;
            }
        }
    };
QLayout*top\u l=layout();//父窗口小部件布局
//找到要在其中搜索的布局
QHBoxLayout*hbox=top_l->findChild(QString(“horizontalLayout_2”);
如果(hbox!=0){

std::cout您可以使用
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()
  }
}
for(int i=0;icount();++i)
{
QWidget*widget=gridLayout->itemAt(i)->widget();
if(小部件!=NULL)
{
小部件->设置可见(假);
}
其他的
{
//您可能希望递归,或者对布局执行不同的操作。
//请参见gridLayout->itemAt(i)->layout()
}
}

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

for(inti=0;ilayout->count();++i){
QWidget*w=this->layout->itemAt(i)->widget();
如果(w!=NULL)
w->setVisible(假);
}

回复一篇旧文章,但我想用一种简单的方法来禁用版面或任何子版面中包含的所有小部件。这对我来说很有用:

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;
}
void setEnabledWidgetsInLayout(QLayout*布局,bool启用)
{
if(布局==NULL)
返回;
QWidget*pw=layout->parentWidget();
如果(pw==NULL)
返回;
foreach(QWidget*w,pw->findChildren())
{
if(IsChildWidgetofAnyalYout(布局,w))
w->setEnabled(已启用);
}
}
bool是childwidgetofanalyout(QLayout*布局,QWidget*小部件)
{
if(布局==NULL或小部件==NULL)
返回false;
如果(布局->索引(小部件)>=0)
返回true;
foreach(QObject*o,布局->子对象())
{
if(ischildwidgetofanalyout((QLayout*)o,小部件))
返回true;
}
返回false;
}

是的,我尝试了children(),但没有任何运气。我无法在创建后进行检查,因为这是从.ui加载的…小部件工作正常…仅与布局有关。关键是布局可以成为小部件的子级(因为它们都继承了
QObject
),但一个小部件不能成为布局的子部件。一个小部件必须有另一个小部件作为父部件,
QLayout
不会继承
QWidget
。布局将它们包含的每个项目包装在一个布局中,因此需要一组不同的API来访问底层对象。这条注释已经有四年历史了,这很糟糕。即使是今天的Qt也是这样做的QLayout跟踪其中的小部件,是私有的d_ptr及其列表属性。子类中不必实现公共API…以返回索引中的布局项。如果没有此类项,函数必须返回0。引用自
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;
}