【问题标题】:How to properly clean-up a QWidget / manage a set of windows?如何正确清理 QWidget/管理一组窗口?
【发布时间】:2012-07-26 02:14:02
【问题描述】:

假设我的应用程序中有 2 个窗口,以及负责它们的两个类: class MainWindow: public QMainWindowclass SomeDialog: public QWidget

在我的主窗口中,我有一个按钮。单击它时,我需要显示第二个窗口。我是这样做的:

SomeDialog * dlg = new SomeDialog();
dlg.show();

现在,用户在窗口中做一些事情,然后关闭它。此时我想从那个窗口获取一些数据,然后,我想,我将不得不delete dlg。但是我如何捕捉到那个窗口被关闭的事件呢?

或者有没有其他方法可以避免内存泄漏?也许在启动时创建每个窗口的实例会更好,然后只是Show()/Hide() 他们?

我该如何处理这种情况?

【问题讨论】:

    标签: c++ qt user-interface qwidget window-management


    【解决方案1】:

    建议使用show() / exec()hide(),而不是每次要显示时动态创建对话框。也使用QDialog 而不是QWidget

    在主窗口的构造函数中创建并隐藏它

    MainWindow::MainWindow()
    {
         // myDialog is class member. No need to delete it in the destructor
         // since Qt will handle its deletion when its parent (MainWindow)
         // gets destroyed. 
         myDialog = new SomeDialog(this);
         myDialog->hide();
         // connect the accepted signal with a slot that will update values in main window
         // when the user presses the Ok button of the dialog
         connect (myDialog, SIGNAL(accepted()), this, SLOT(myDialogAccepted()));
    
         // remaining constructor code
    }
    

    在连接到按钮的clicked() 事件的插槽中简单地显示它,并在必要时将一些数据传递给对话框

    void myClickedSlot()
    {
        myDialog->setData(data);
        myDialog->show();
    }
    
    void myDialogAccepted()
    {
        // Get values from the dialog when it closes
    }
    

    【讨论】:

      【解决方案2】:

      QWidget 的子类并重新实现

      virtual void QWidget::closeEvent ( QCloseEvent * event )

      http://doc.qt.io/qt-4.8/qwidget.html#closeEvent

      此外,您要显示的小部件看起来像是一个对话框。所以考虑使用QDialog 或者它的子类。 QDialog 有有用的信号可以连接到:

      void    accepted ()
      void    finished ( int result )
      void    rejected ()
      

      【讨论】:

        【解决方案3】:

        我认为您正在寻找 Qt::WA_DeleteOnClose 窗口标志:http://doc.qt.io/archives/qt-4.7/qt.html#WidgetAttribute-enum

        QDialog *dialog = new QDialog(parent);
        dialog->setAttribute(Qt::WA_DeleteOnClose)
        // set content, do whatever...
        dialog->open();
        // safely forget about it, it will be destroyed either when parent is gone or when the user closes it.
        

        【讨论】:

        • ctor 采用窗口标志,而不是小部件属性。正确的调用是 dialog->setAttribute(Qt::WA_DeleteOnClose)
        • @FrankOsterfeld 谢谢。我输入时无法编译,所以我从未检查过。
        • @FrankOsterfeld 关闭对话意味着什么?假设我有一个按钮并调用插槽 close(),那么会发生什么?对话框会从内存中清除吗?
        • 如果我使用 deletelater() 而不是 close() 会发生什么?
        猜你喜欢
        • 2010-12-15
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 2022-08-16
        • 1970-01-01
        • 1970-01-01
        • 2011-01-29
        • 1970-01-01
        相关资源
        最近更新 更多