删除指向小部件 Qt C++ 的指针 [英] Deleting Pointer to widget Qt C++

查看:126
本文介绍了删除指向小部件 Qt C++ 的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Qt 的新手,我对如何删除小部件感到非常困惑.我正在阅读一个视频,我想在读取视频帧时显示一个 QProgressbar,然后在加载视频时删除这个 QProgressbar.

I am new with Qt and i am very confused about how widgets are deleted. I was reading a video and i wanted to show up a QProgressbar while the video frames are being read and then remove this QProgressbar when the video is loaded.

我用了两种不同的方法:

I have done it with 2 different ways:

  1. 使用指针

  1. Using Pointers

QWidget* wd = new QWidget();
QProgressBar* pB = new QProgressBar(wd);
QLabel* label = new QLabel(wd);
//setting geometry and updating the label and progressbar
wd->deleteLater();
wd->hide();

这段代码写在一个类中,我假设当这个类的析构函数被调用时,这个小部件将连同它的所有孩子一起被删除,但这并没有发生,每次我再次运行这个函数时,一个新的小部件是创建时没有隐藏或删除前一个(注意:我试图从小部件中删除标签和进度条,假设它们将从小部件内部消失,但这并没有发生删除(pB);")

this code is written inside a class and i was assuming when the destructor of this class is called, the widget will be deleted with all of it's children but that didn't happen and everytime i run this function again a new widget is created without hiding or deleting the previous one (NOTE: i have tried to delete the label and progressbar from the widget assuming that they will disappear from inside the widget but this didn't happen "delete(pB);")

使用对象

    QWidget wd;
    QProgressBar pB(&wd);
    QLabel label(wd);
    //setting geometry and updating the label and progressbar
    wd.deleteLater();
    wd.hide();

当我运行相同的代码但使用对象而不是指针时,它完全按照我的要求运行,每次我运行该函数时,旧小部件都会被销毁并创建一个新小部件.

When i have run the same code but using objects instead of pointers , it has run exactly as i have wanted and everytime i run the function, the old widget is destroyed and a new one is created.

注意:-此外,当我关闭主窗口时,在出现指针的情况下,小部件 wd 仍然存在并且程序不会终止,直到我手动关闭它们- 在对象的情况下,当我关闭主窗口时,一切都会关闭并且程序正确终止.

NOTE: -Also when i close the main window, in case of pointers, the widget wd still exists and the program doesn't terminate until i close them manually - In case of Objects, when i close the main window everything is closed and the program is terminated correctly.

我需要有人向我解释为什么会发生这种情况,以及如果我有一个指向小部件的指针向量来删除该向量中的所有指针而不会出现任何内存泄漏,该怎么办

I need someone to explain me why is this happening and how if i am having a vector of pointers to widgets to delete all pointers inside that vector without any memory leakage

推荐答案

一切都很简单.QObject 派生类与任何其他 C++ 类一样,只有一个例外:如果 QObject 有子级,它将删除其析构函数中的子级.请记住,QWidget 是一个 QObject.如果你有一个使用new`分配的实例,你必须删除它,或者确保某些东西(智能指针!)可以.

It's all really simple. QObject-derived classes are just like any other C++ class, with one exception: if a QObject has children, it will delete the children in its destructor. Keep in mind that QWidget is-a QObject. If you have an instance allocated usingnew`, you must delete it, or ensure that something (a smart pointer!) does.

当然,尝试删除一些你没有动态分配的东西是一个错误,因此:

Of course, attempting to delete something you didn't dynamically allocate is an error, thus:

  1. 如果不动态分配QObject不要 deleteLaterdelete

如果您不动态分配 QObject 的孩子,请确保它们在对象被破坏之前消失.

If you don't dynamically allocate a QObject's children, make sure they are gone before the object gets destructed.

此外,不要隐藏您将要破坏的小部件.毫无意义.

要自己管理小部件生命周期,您应该使用智能指针:

To manage widget lifetime yourself, you should use smart pointers:

class MyClass {
  QScopedPointer<QWidget> m_widget;
public:
  MyClass() :
    widget{new QWidget};
  {
    auto wd = m_widget->data();
    auto pb = new QProgressBar{wd};
    auto label = new QLabel{wd};
  }
};

当您销毁 MyClass 时,作用域指针的析构函数将删除小部件实例,其 QObject::~QObject 析构函数将删除其子项.

When you destroy MyClass, the scoped pointer's destructor will delete the widget instance, and its QObject::~QObject destructor will delete its children.

当然,这些都不是必需的:您应该简单地将对象创建为类的直接成员:

Of course, none of this is necessary: you should simply create the objects as direct members of the class:

class MyClass {
  // The order of declaration has meaning! Parents must precede children.
  QWidget m_widget;
  QProgressBar m_bar{&m_widget};
  QLabel m_label{&m_widget};
public:
  MyClass() {}
};

通常您会为子小部件使用布局:

Normally you'd be using a layout for the child widgets:

class MyClass {
  QWidget m_widget;
  QVBoxLayout m_layout{&m_widget};
  QProgressBar m_bar;
  QLabel m_label;
public:
  MyClass() {
    m_layout.addWidget(&m_bar);
    m_layout.addWidget(&m_label);
  }
};

当您将小部件添加到布局时,它会将它们重新设置为设置了布局的小部件.

When you add widgets to the layout, it reparents them to the widget the layout has been set on.

编译器生成的析构函数如下所示.你不能写这样的代码,因为编译器生成的代码会双重销毁已经销毁的对象,但让我们假设你可以.

The compiler-generated destructor looks as below. You can't write such code, since the compiler-generated code will double-destroy the already destroyed objects, but let's pretend you could.

MyClass::~MyClass() {
  m_label.~QLabel();
  m_bar.~QProgressBar();
  m_layout.~QVBoxLayout();
  // At this point m_widget has no children and its `~QObject()` destructor
  // won't perform any child deletions.
  m_widget.~QWidget();
}

这篇关于删除指向小部件 Qt C++ 的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆