【问题标题】:Qt: RemoveWidget and object deletionQt:RemoveWidget 和对象删除
【发布时间】:2012-07-22 09:54:01
【问题描述】:

我一直在阅读 Qt 文档并玩弄 qobject 树。我想知道是否有一种方法可以从树中删除小部件,从而将它们从内存中删除。

当相互嵌入 qwidgets/qobjects 并创建树时,从 qlayouts 中删除带有 removeWidget 的小部件将在 gui 中可视地删除它们,但是该对象仍保持连接到父 qobject(object->parent() 不是0),只有在其父级被删除后才会被删除(例如超出范围)。我只能看到一个 qwidget 只有在应用程序终止时才能被销毁,其中顶部小部件将其下面的所有内容(或者如果对象超出范围)。

例如,假设有一个具有 2 个阶段的主窗口:第一个具有从一个父级嵌入的大约 100 个对象,另一个具有 200 个。应用程序从第 1 阶段开始并移至第 2 阶段,它永远不会返回到第 1 阶段。如果我希望这有点效率,我会尝试杀死第 1 阶段中的所有对象(100 个对象),但因为它们附加到主窗口的根节点,即使使用“removeWidget”也无法销毁”。

我还尝试接收在没有“new”运算符的情况下创建的小部件的指针,如果我删除该对象,应用程序将崩溃,因为它会调用析构函数两次。

我的问题是,有没有办法删除 qobject 树中的节点(该节点没有被删除,因为它超出范围或应用程序终止时)?

对不起,如果这没有多大意义。提前致谢。

编辑:

对不起,如果我给出了错误的想法。我的问题是在应用程序终止之前或对象超出范围之前从内存中删除一个节点。这是一个例子(可能不太好)。

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Test w;
    w.show();

    QHBoxLayout *layout = new QHBoxLayout();
    w.setLayout(layout);

    Test heavyObj;             //I know you can use pointers instead and that 
                               //would allow you to easy delete the object
                               //but say if I did this instead.
    w->addWidget(&heavyObj);

    for(int i=0; i < 200; i++) {
        Test obj(heavyObj);
    }

    w->removeWidget(&heavyObj); //At this point we don't want "heavyObj", I want
                                //to delete this object from memory
                                // is it possible to remove p1 from memory?

    return a.exec();

    //As stated, once the program terminates everything is destroyed
}

【问题讨论】:

    标签: c++ qt qwidget removechild qobject


    【解决方案1】:

    调用removeWidget()后,删除delete yourWidgetPointer;的对象。 QObject 的析构函数将负责将子对象注销到父对象。

    【讨论】:

    • 但是,如果您在没有“new”的情况下初始化对象,您就不能这样做,对吧?您将不得不让它超出范围?
    • 是的。如果您想要更细粒度地控制何时从堆栈中清除对象,您可能想要使用 scoped_ptr。此外,为了确保对象超出范围,定义一个狭窄的范围(使用花括号)通常并不难。
    • 有没有办法从 qobject 树中删除一个节点而不使用指针并在其上调用 delete 或者我必须等待该对象超出范围?是否有任何时候我不想将 qwidget 初始化为指针?
    • 有没有办法:不行。堆栈上的对象不能删除。有时间在堆栈上创建 QWidget 吗? A:是的,诸如对话框之类的顶级窗口,仅在方法执行期间存在。
    • 感谢您的洞察力。我现在明白了。
    【解决方案2】:

    当 QObjects 在堆上创建(即用 new 创建)时,一棵树 可以以任何顺序从它们构造,然后, 这棵树可以按任何顺序被摧毁。当树中的任何 QObject 被删除,如果对象有父对象,析构函数自动 从其父对象中删除对象。如果对象有子对象,则 析构函数自动删除每个孩子。 没有 QObject 被删除 两次,无论破坏顺序如何。

    取自here

    我不知道你在问什么,如果你删除一个对象,它会从它的父级中删除,然后删除它拥有的所有子级(这会从你正在删除的内容中向下级联子树)。请显示您正在调用的导致段错误的代码,因为您应该能够在树中的任何位置删除(使用delete)任何QObject,并且树将自行重组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 2012-06-17
      相关资源
      最近更新 更多