2010-10-31 136 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; 
}