2010-10-31 94 views
20

我尝试隐藏布局中的所有小部件。但看起来像findChildren不 工作的布局。Qt从布局中获取儿童

这里是我的示例代码:

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

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

大小为0,但这种布局里面,我有几个小部件。 但是,如果我尝试从父窗口小部件中获取小部件,相同的代码工作正常。

如何让他们从适当的布局?

感谢,

回答

24

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

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

+4

关键是,布局可以成为一个小部件的孩子(因为他们都继承'QObject'),但小部件不能成为布局的子元素。一个窗口小部件必须有另一个窗口小部件作为父窗口,'QLayout'不会继承'QWidget'。 Layouts将包含在['QLayoutItem'](http://doc.qt.io/qt-4.8/qlayoutitem.html#QLayoutItem)中的每个项目中,因此需要一组不同的API来访问基础对象。 – ekhumoro 2015-05-13 16:26:42

-1

你尝试children()方法,而不是findChildren()?也许你从widget -> findChild<QLayout *> (layoutName)方法得到'坏'布局。尝试在创建布局后立即找到孩子 - 所以你确定布局是正确的。这样做,你将能够确定哪些功能工作错误。

+0

是的我试过儿童(),没有任何运气。我不能在创建后检查,因为这是从.ui加载...对于小部件工作正常...只发布与布局.. – 2010-10-31 23:27:23

1

由于布局不小部件层次结构的一部分,小部件必须从父查询,但随后的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; 
      } 
     } 
    }; 
19

你可以简单地在布局的项目迭代使用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() 
    } 
} 
1

这是非常晚,但如果有人发现这里像我这样的,这里是我的解决方案: 我试图@braggPeaks答案(这是同@Frank奥斯特费尔德答案)但它f ailed。然后我像这样修改,它就像一个魅力。 (我不知道为什么它会奏效,因为我的布局有没有空的项目,但我仍然要检查是否有。)

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