我正在使用構造函數QWidget(QWidget *parent)
。這個父窗口小部件包含很多子窗口小部件。我需要在運行時從父級清除所有子部件。我怎樣才能做到這一點?如何清除父窗口小部件中的所有窗口小部件?
回答
您可以使用您的父控件類以下內容:
QList<QWidget *> widgets = findChildren<QWidget *>();
foreach(QWidget * widget, widgets)
{
delete widget;
}
以前的答案是錯的!您不能使用findChildren
刪除小部件的子項,因爲Qt4的findChildren
遞歸列出子項。因此,您將刪除可能會被刪除兩次的兒童,這可能會導致應用程序崩潰。
更一般地,在Qt中,服用的QObject
指針的列表,並通過一個刪除它們一個是危險的,因爲破壞對象可以鏈破壞其它的目的,由於父所有權機制,或通過destroyed()
信號連接到一個deleteLater()
插槽。因此,銷燬列表中的第一個對象可能會使下一個對象失效。
你需要列出孩子要麼通過小部件:
- 傳遞了Qt :: FindDirectChildrenOnly標誌,如果你正在使用QT5到findChild(當有人問並不存在...)
- 使用QLayout函數列出項目,
- 使用QObject :: children,並且對於每個測試,如果它是使用isWidgetType()或者演員組件的widget,空指針
照顧遞歸性問題,指出了@galinette你可以只取出部件在while循環
while (QWidget* w = findChild<QWidget*>())
delete w;
這是我看來最合適的答案 – Michal 2015-02-18 08:40:26
從Qt的docs
下面的代碼片段展示了一個安全的方式來從佈局中刪除所有項目:
QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
...
delete child;
}
總結和補充:
對於QT5在一條線:
qDeleteAll(parentWidget->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
對於QT5了很多孩子,使用setUpdatesEnabled():
parentWidget->setUpdatesEnabled(false);
qDeleteAll(parentWidget->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
parentWidget->setUpdatesEnabled(true);
請注意,這不是異常安全的!雖然Qt此時並不會在這裏拋出異常,但destroy()的信號可能會連接到拋出的代碼,或者被覆蓋的Object :: childEvent(QChildEvent *)可能拋出。
更好的辦法是使用一個輔助類:
class UpdatesEnabledHelper
{
QWidget* m_parentWidget;
public:
UpdatesEnabledHelper(QWidget* parentWidget) : m_parentWidget(parentWidget) { parentWidget->setUpdatesEnabled(false); }
~UpdatesEnabledHelper() { m_parentWidget->setUpdatesEnabled(true); }
};
...
UpdatesEnabledHelper helper(parentWidget);
qDeleteAll(parentWidget->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
對於的Qt4:
QList<QWidget*> childWidgets = parentWidget->findChildren<QWidget*>();
foreach(QWidget* widget, childWidgets)
if (widget->parentWidget() == parentWidget)
delete widget;
從QLayout刪除工作在兩個的Qt4和QT5:
QLayoutItem* child;
while (NULL != (child = layout->takeAt(0))) // or nullptr instead of NULL
delete child;
的QObject s(因此QWidgets)會從它們的(QObject)析構函數中的父級中刪除它們(自動)。
- 1. 沒有佈局的父窗口小部件上的中心窗口小部件
- 2. 父窗口小部件如何定位其子窗口小部件?
- 3. 如何添加複合窗口小部件:這個窗口小部件的父窗口沒有實現HasWidgets
- 4. 如何禁用父窗口小部件中的所有用戶輸入窗口小部件(按鈕,條目..)?
- 5. 窗口小部件
- 6. PyQt - 調整父級窗口小部件的子窗口大小
- 7. 如何在窗口中調整窗口小部件的大小
- 8. 如何從窗口中刪除Tkinter窗口小部件?
- 9. 放入CDetailView窗口小部件另一個窗口小部件
- 10. 從窗口訪問窗口小部件*
- 11. 從窗口中刪除小部件
- 12. Qt窗口小部件,是否必須將包含窗口小部件設置爲父窗口?
- 13. 父窗口小部件中的中心固定大小的GtkDrawingArea小部件
- 14. MVC窗口小部件
- 15. Qt的刪除窗口小部件
- 16. Qt - 調用窗口小部件父窗口
- 17. 創建窗口上的窗口小部件出現在父窗口上
- 18. 調用窗口小部件中的另一個窗口小部件會失去所有窗口小部件的屬性
- 19. Dashing - 動態刪除窗口小部件
- 20. QGraphicsView渲染它的子窗口小部件的子窗口小部件
- 21. PySide - 重置中央窗口小部件中的主窗口中央窗口小部件
- 22. 調整無窗口小部件的窗口大小
- 23. Qt選項卡窗口小部件添加角組窗口小部件
- 24. PyQt4 - 使子窗口小部件縮小以適應父窗口和佈局
- 25. 縮小父窗口,而不是其他窗口小部件增長
- 26. 將子窗口小部件的關鍵事件重定向到其父窗口小部件
- 27. 如何將事件傳遞給父窗口小部件
- 28. 如何刪除小部件並調整主窗口大小?
- 29. 事件的回調窗口小部件
- 30. 在Android窗口小部件中的GridView
問題的答案http://stackoverflow.com/questions/4272196/qt-remove-all-widgets-from-layout/18496300#18496300可能是相關的。 – 2013-08-28 19:15:31