Управление памятью дочерних диалоговых окон - PullRequest
0 голосов
/ 05 октября 2018

Я использую следующий код для отображения окна MyWindowClass, которое является подклассом QDialog:

//header mainwindow.h
MyWindowClass *myWindow;

//mainwindow.cpp
void MainWindow::on_actionButton_triggered()
{
    myWindow = new MyWindowClass(this);
    myWindow->show();
}

Я прочитал в StackOverflow, что this управляет удалением объекта:

окно удаляется, когда родительский элемент mainWindow удаляется.

Когда я открываю диспетчер задач Windows и смотрю на объем оперативной памяти, моя программаиспользуя, используемая память увеличивается каждый раз, когда открывается новое диалоговое окно.

Пока все хорошо.Однако, когда я закрываю диалоговое окно (не mainWindow), используемая оперативная память уменьшается, что означает, что память освобождается Qt.

Как и в цитате, я ожидаю, что диалоговые окна будут удаленыкак только родитель mainWindow удален.

Я ошибся?

Ответы [ 3 ]

0 голосов
/ 05 октября 2018

Qt имеет функцию, называемую родительско-дочерними отношениями, в которой объект, созданный вами с помощью указателя this, является дочерним, а объект, на который указывает указатель this, является родительским.В основном это говорит, что всякий раз, когда родительский объект удаляется, объект удаляется.Таким образом, в вашем случае, когда родительский объект был удален, все дочерние объекты также были удалены.Этот механизм только гарантирует, что дочерние объекты будут удалены, ЕСЛИ И ТОЛЬКО ЕСЛИ родитель удален.Если вы думали, что Qt удаляет дочерний объект, когда ваше диалоговое окно было закрыто, то вы ошибаетесь.Лучше использовать умные указатели, если вы беспокоитесь о памяти, так как qt освобождает память, только если родитель удален.

0 голосов
/ 07 октября 2018

Скорее всего, у вас есть следующая строка в конструкторе вашего подкласса QDialog:

setAttribute(Qt::WA_DeleteOnClose);

Это делает возможным автоматическое удаление дочернего диалога MyWindowClass, когда он закрыт, сродительское окно MainWindow все еще открыто.

Документация Qt::WA_DeleteOnClose гласит:

Заставляет Qt удалить этот виджет, когда виджет принялсобытие close (см. QWidget :: closeEvent ()).

Следующий пример, который я подготовил для вас, демонстрирует эффект:

#include <QApplication>
#include <QMainWindow>
#include <QPushButton>
#include <QDialog>

class MainWindow : public QMainWindow
{
//  Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr) :
        QMainWindow(parent)
    {
        auto *button = new QPushButton(tr("Open dialog"), this);

        setCentralWidget(button);

        connect(button, &QPushButton::clicked, [this](){
            auto *dialog = new QDialog(this);

            dialog->setAttribute(Qt::WA_DeleteOnClose);
            dialog->resize(300, 200);
            dialog->show();

            connect(dialog, &QDialog::destroyed, [](){
                qDebug("Dialog's gone.");
            });
        });
    }
};

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

    return a.exec();
}

Этот код позволяет новому пустому диалогубыть открытым при каждом нажатии кнопки.Если диалоговое окно закрыто, в консоли выводится Dialog's gone..

Комментирование строки

dialog->setAttribute(Qt::WA_DeleteOnClose);

в примере предотвращает автоматическое удаление объектов диалогового окна, поэтому сообщение не будетпечататься при закрытии диалогового окна.

0 голосов
/ 05 октября 2018

Да, именно так.Он обрабатывается объектом QObject, который наследуется в QDialog (через QWidget).

Вы передаете указатель на родительский QObject, когда используете this, а родительский объект заботится о памятиосвобождение всех дочерних элементов при уничтожении родителя (в данном случае при закрытии программы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...