如何清除父Widget中的所有Widget?
我正在使用构造函数QWidget(QWidget *parent)
。这个父窗口部件包含很多子窗口部件。我需要在运行时清除父级的所有子级小部件。我该怎么做?
I am using the constructor QWidget(QWidget *parent)
. This parent widget contains a lot of child widgets. I need to clear all the child widgets from the parent at runtime. How can I do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
之前的答案是错误的!!您不能使用
findChildren
删除小部件的子项,因为 Qt4 的findChildren
递归地 列出子项。因此,您将删除子项的子项,然后可能会删除两次,从而可能导致您的应用程序崩溃。更一般地,在 Qt 中,获取 QObject 指针列表并逐个删除它们是危险的,因为由于父所有权机制,或者通过连接一个对象,销毁一个对象可能会连锁销毁其他对象。
destroyed()
向deleteLater()
槽发出信号。因此,销毁列表中的第一个对象可能会使接下来的对象无效。您需要通过以下方式列出子窗口小部件:
Previous answer is wrong!! You cannot use
findChildren
to delete a widget's children, because Qt4'sfindChildren
recursively lists children. Therefore, you will delete children of children, which then may be deleted twice, potentially crashing your app.More generally, in Qt, taking a list of
QObject
pointers and deleting them one by one is dangerous, as destroying an object may chain-destroy other objects, due to the parent ownership mechanism, or by connecting adestroyed()
signal to adeleteLater()
slot. Therefore, destroying the first objects in the list may invalidate the next ones.You need to list children widgets either by:
要解决 @galinette 指出的递归问题,您只需在 while 循环中删除小部件即可
To take care of the recursivity problem pointed out by @galinette you can just remove the widgets in a while loop
总结补充:
对于Qt5一行:
对于Qt5对于很多孩子来说,使用setUpdatesEnabled():
注意,这不是异常安全的!虽然 Qt 此时似乎不会在此处抛出异常,但信号 destroy() 可以连接到确实抛出异常的代码,或者重写的 Object::childEvent(QChildEvent*) 可能会抛出异常。
更好的方法是使用辅助类:
...
对于 Qt4:
从 QLayout 中删除在 Qt4 和 Qt5 中都有效:
QObject(以及 QWidget)在其 (QObject) 析构函数中从其父级中(自动)删除自身。
Summarizing and supplementing:
For Qt5 in one line:
For Qt5 for a lot of children, using setUpdatesEnabled():
Note that this is not exception safe! While Qt does not at this time appear to throw exceptions here, the signal destroyed() could be connected to code that does throw, or an overridden Object::childEvent(QChildEvent*) could throw.
Better would be to use a helper class:
...
For Qt4:
Removing from the QLayout works in both Qt4 and Qt5:
QObjects (and therefore QWidgets) remove themselves (automagically) from their parent in their (QObject) destructor.
来自 Qt docs
以下代码片段显示了删除所有项目的安全方法从布局:
From Qt docs
The following code fragment shows a safe way to remove all items from a layout:
您可以在父小部件类中使用以下内容:
You can use the following in your parent widget class: