2010-06-10 40 views
10

这似乎是一个很简单的问题,但我想转储一些数据每当QMainWindow关闭,所以我用下面的代码:的Qt的QMainWindow在关闭

QObject::connect(MainWindow.centralwidget, SIGNAL(destroyed()), this, SLOT(close())); 

但这似乎并不拨打电话close()。我做错了吗?
中央部件是不是会被摧毁?

或者应用程序关闭之前可以调用close()

还有其他方法吗?

+0

'this'适合你的'QObject'层次结构吗?信号发送前可能会被删除。当然,我不会为此担心,因为迄今为止给出的答案中有更好的选择。 – Troubadour 2010-06-10 17:54:55

+0

你不能用你显示的代码转储数据......还有你的问题是如何在QMainWindow关闭之前转储数据?或为什么QMainwindow没有关闭?请明确... – liaK 2010-06-10 17:57:17

+1

我想单击'x'关闭主窗口后写入XML文件。它似乎没有与上面的代码或QApplication :: lastWindowClosed()(或QApplication :: aboutToQuit()的问题)...没有尝试过QCloseEvent,但保持MVC结构,我宁愿不。我正在使用的类不是QMainWindow,而是使用通过编译在设计器中创建的ui文件获得的文件。 – Cenoc 2010-06-10 18:09:30

回答

10

我想试试。

+0

没有工作,必须表示它在该信号可以被接受之前被销毁?但这很奇怪,因为类的析构函数似乎没有输出任何东西(通过std :: cerr) – Cenoc 2010-06-10 18:07:08

+0

确保带有插槽的对象不是QMainWindow的子项。 QWidgets在他们失踪时摧毁所有的孩子。 – 2010-06-10 18:15:33

+0

@Cenoc:发布你的'main'函数,它可以帮助清理正在发生的事情。 – 2010-06-10 18:18:56

4

您能否为您的QMainWindow实现closeEvent函数并将代码放在那里?

1

您的第一个问题和代码不匹配。如果您想在QMainWindow上执行某项操作,请创建一个子类并重新执行closeEvent或连接到MainWindow::destroyed()。然而,请参阅第3段的说明。

但是你的代码显示的是第三类,它将MainWindow的孩子连接到一个名为close()的插槽。 centralwidget将被销毁后,MainWindow已被破坏,所以这最有可能不会帮助你。

此外,这取决于你如何创建MainWindow(堆栈或堆),如果你正确地破坏它。理想情况下,你应该创建一个QMainWindow的子类(如果你使用了设计器,你可能已经有了)。

22

你最好重新实现在主MainWindow类一个虚函数是这样的:

class MainWindow : public QMainWindow { 

    Q_OBJECT; 

public: 
    MainWindow(); 

protected: 
    void closeEvent(QCloseEvent *event); 
} 

,然后在源文件中声明:

void MainWindow::closeEvent(QCloseEvent *event) { 
    // do some data saves or something else 
} 

好运。

+2

完成覆盖是个好主意。 IE:在closeEvent()中调用QMainWindow :: closeEvent(event);在函数结束时。请参阅saveState()函数的文档中的示例:http://doc.qt.io/qt-4.8/qmainwindow.html – Ph0t0n 2017-01-19 20:38:03

+0

虽然Ph0t0n不一定是错的,但通常情况下,实际的'closeEvent()'实现根据未保存的更改是否存在,调用event.accept()或event.ignore()。 'QMainWindow :: closeEvent(event)'通常不会被调用。有关另一个有用的示例,请参见['closeEvent()'文档](http://doc.qt.io/archives/qt-4.8/qwidget.html#closeEvent)。 – 2017-12-23 08:00:26

-1

如何将转储代码添加到主窗口的析构函数?

+0

试过,它不输出....奇怪? – Cenoc 2010-06-10 18:05:54

+0

您无法访问已销毁的I/O或MainWindow的析构函数 - 您终于进入您的应用程序析构函数,并且所有内容都被销毁。改用closeEvent()。 – Jens 2010-06-10 18:15:45

1

在您的班级中实施QMainWindow::closeEvent(QCloseEvent *)。然后实施一个名为closing()的新信号,并从您的实施QMainWindow::closeEvent()中发出。然后,您可以连接到该信号,在关闭窗口之前执行一些操作。你也可以直接使用closeEvent来做你需要做的事情,比如保存状态,同步数据或其他。

1

enter image description here 在Python(PyQt4的或pyqt5),你需要做到以下几点:

class MyWindow(QMainWindow): 
    def __init__(self): 
     super(MyWindow, self).__init__() 
     # 
     # My initializations... 
     # 

    '''''' 

    def closeEvent(self, *args, **kwargs): 
     # 
     # Stuff I want to do when this 
     # just before (!) this window gets closed... 
     # 

    '''''' 

有趣的是,知道在的closeEvent(..)东西函数被刚执行之前  窗户关闭。

# Test if the closeEvent(..) function 
    # executes just before or just after the window closes. 
    def closeEvent(self, *args, **kwargs): 
     # 'self' is the QMainWindow-object. 
     print(self) 
     print(self.isVisible()) 

     # Print out the same stuff 2 seconds from now. 
     QTimer.singleShot(2000, lambda: print(self)) 
     QTimer.singleShot(2100, lambda: print(self.isVisible())) 

    '''''' 

这是你的终端输出:

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
True 

<myProj.MyWindow object at 0x000001D3C3B3AAF8> 
False 

这证明窗口仍然进入时的closeEvent可见(..)功能,您可以用下面的测试验证这一点,但不是在退出该功能之后。