2010-06-10 41 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可見(..)功能,您可以用下面的測試驗證這一點,但不是在退出該功能之後。