【问题标题】:Qt - How to handle memory management for dialogs?Qt - 如何处理对话框的内存管理?
【发布时间】:2019-09-27 19:29:50
【问题描述】:

我遇到了以下问题:

  • 用户按下“Ctrl+N”进入函数 MainWindow::newAction()
  • 在 MainWindow::newAction() 中,创建一个 QDialog dlg(centralWidget()) 并调用 dlg.exec()
  • dlg 打开时,用户再次按下“Ctrl+N”

结果是 dlg 永远不会被删除(只有在 centralWidget() 被删除后才会被删除)。

调用栈是这样的:

MainWindow::newAction ()
...
MainWindow::newAction()

我想知道如何处理这种情况。我希望在我们再次进入函数 newAction() 时删除第一次调用 newAction() 的所有本地对话框变量。

【问题讨论】:

  • 试着让你的对话模式化。对话框打开时,用户将无法与您的主窗口进行交互。

标签: c++ qt memory


【解决方案1】:

你也可以试试这样的:

void MainWindow::newAction() {

    const auto dialog = new MyDialog(centralWidget());

    // When user will close the dialog it will clear itself from memory
    connect(dialog, &QDialog::finished, [dialog]() {
        dialog->deleteLater();
    });

    dialog->exec();
}

但是,一个好的举措是阻止用户召唤比单个更多的 QDialogs,因为这是一个模态对话框(将这个对话框指针保留为类成员并检查它是否打开可能是个好主意在调用 exec() 之前已经显示屏幕。

【讨论】:

    【解决方案2】:

    如果我对问题的理解正确,您希望打开一个对话框并希望在收到新的对话框请求之前将其删除?

    如果是这种情况,您可以执行以下操作:

    MainWindow.h 中声明QDialog *dlg = nullptr

    在您的 MainWindow.cpp newAction() 函数中,您可以执行以下操作:

    void newAction()
    {
       if(dlg != nullptr)
       {
        dlg->close();
        dlg->deleteLater();
        //or
        //dlg->destroy(); // this will immediately free memory
       }
       dlg = new QDialog(centralWidget());
       ...
       //dlg->exec(); // This will automatically make QDialog modal.
       dlg->show(); // This will not make a QDialog modal. 
    }
    

    我希望这会有所帮助。记住 QDialogs 当与exec() 一起显示时,它们会自动表现为模态窗口。 show() 将使其成为非模态的。

    【讨论】:

    • QObject 上使用delete 是个坏主意(删除后它可能会收到事件,应用程序会崩溃)。请改用QObject::deleteLater()
    • @RomhaKorev 我同意你的看法。我更新了我的答案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-30
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2017-08-21
    • 2020-08-21
    相关资源
    最近更新 更多