7

这是MainWindow我调用并使用该函数show()使其对用户可见的类。

class MainWindow : public QMainWindow
{
    Q_OBJECT

    QWidget *centralWidget;
    QGridLayout* gridLayout;
    QGridLayout* infoBoxLayout;
    QHBoxLayout* buttonGroup;
    QHBoxLayout* subCategoryLayout;
    //... more widgets

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void setupUi();
    void setupConnections();

private slots:
    void add();
    void edit();
    void remove();
    void find();
    void clearAll();
    void screenshotDesktop();
    void screenshotApp();

    void currentSubCategoryChanged( const QString& );
    void curretCategoryChanged( const int );

    void keyPressEvent( QKeyEvent * );

};

我为每个小部件(宏之后的那些指针Q_OBJECT)在堆上创建了一个新对象new。但是,我没有在程序的任何地方删除它们。这会导致 Qt 中的内存泄漏吗?或者 Qt 中的某些东西在销毁类时会自动删除它们吗?

4

3 回答 3

14

如果一个小部件有一个父集,那么 Qt 将处理删除这个小部件。在 MainWindow 的情况下,当您关闭它时,MainWindow 及其子级将被清理,因此将父级传递给小部件的构造函数:-

QHBoxLayout* buttonGroup = new QHBoxLayout(this); // where this is the parent (MainWindow)

如果您创建这样的小部件:-

QHBoxLayout* buttonGroup = new QHBoxLayout;

并且还没有传入父母,那么它不会被清理,你必须自己处理。

于 2013-09-26T14:10:45.140 回答
5

MainWindow如果您将它们添加到 gui 层次结构中,那么它们将在被删除时被清理

这是因为父母对他们的孩子拥有所有权(这是由 gui 的各种添加设置的)

所以this->add(centralWidget);会调用centralWidget->setParent(this);它会centralWidget在被删除时MainWindow被删除

您可以自己删除 QObjects,但要注意悬空指针(QPointer 将在此处提供帮助)。虽然我建议使用deleteLater()以确保当指针仍然存在于堆栈上时不会出现奇怪的行为。

有关对象树的更多信息,请参见此处

于 2013-09-26T14:12:59.130 回答
1

通过父子关系的自动内存管理由QObject. QWidget恰好是 a QObject,并且具有父小部件的小部件具有与父小部件相同的底层 QObjects。

带有子对象的 QObject 会在其析构函数中自动删除其子对象。

一个 QObject 或一个 QWidget 可能被另一个对象采用。例如,将小部件添加到布局将自动将它们重新设置为设置布局的小部件。即使布局上还没有设置小部件,在您将布局添加到小部件(或具有小部件集的布局)时,也会完成重新设置。它非常聪明,可以节省大量打字并减少出错的可能性。

将小部件添加到另一个小部件的惯用、最少输入方式是:

MyWidget() {
  QLayout * layout = new QHBoxLayout(this); // set a layout on this widget
  layout->addWidget(new QLabel("foo")); // the label is reparented to this
  layout->addWidget(new QPushButton("bar")); // the button is reparented to this
}
于 2013-09-26T17:46:32.623 回答