原文:https://www.cnblogs.com/parzulpan/p/13720827.html
前言#
最近在寫一個開源項目,需要實現一個程序自動重啟的功能。嘗試了好幾種方式,效果均不太理想。
一開始的實現思路是,記為思路一吧。大概就是寫一些 shell 腳本,然后在需要自動重啟的地方關閉當前程序,然后開一個進程執行這個 shell 腳本。
先來說一說這個關閉吧,主要的方法有:
QCoreApplication::exec() // 進入主事件循環,並等待直到調用exit(),返回傳遞給值exit()。必須調用此函數來開始事件處理。主事件循環從窗口系統接收事件,並將事件分派給應用程序小部件。 QCoreApplication::exit(0); // 告訴應用程序退出並返回代碼。調用此函數后,應用程序將離開主事件循環,並從調用返回至exec()。該EXEC()函數返回返回碼。如果事件循環未運行,則此功能不執行任何操作。 // 按照慣例,returnCode為0表示成功,並且任何非零值都表示錯誤。QApplication::exit(0);等價於它。 QCoreApplication::quit(); // 告訴應用程序退出,返回碼為0(成功)。等效於調用QCoreApplication::exit(0); QApplication::quit();等價於它。 close(); // QApplicatio有個常用屬性qApp->quitOnLastWindowClosed(true),當最后一個窗口關閉時自動調用前面的exit()。 QApplication::closeAllWindows(); // 關閉多個窗口,比調用quit好,因為窗口可以接受到 close 事件。
接着來說思路一:關閉之后,然后開一個進程執行這個 shell 腳本。發現舊應用沒有自動關閉,並且也啟動了新應用,關閉舊應用發現新應用也同時關閉。之后分析原因之后發現,因為使用的是 Python 的 multiprocessing 模塊提供的一個Process類來代表一個進程,此時新舊應用兩個之間是存在父子關系的,所以才會造成這種結果。
實現#
走了上面的坑了后,查看官方文檔可以知道,Qt 中常用的實現重啟的方式有兩種:
- 進程控制:即退出當前進程,再通過 QProcess 啟動一個新的進程。
- 事件循環:退出應用程序,然后通過 Application 事件循環控制程序啟動。
進程控制#
def restart_real_live(): """ 進程控制實現自動重啟 :return: """ qApp.quit() # QProcess 類的作用是啟動一個外部的程序並與之交互,並且沒有父子關系。 p = QProcess # applicationFilePath() 返回應用程序可執行文件的文件路徑 p.startDetached(qApp.applicationFilePath())
事件循環#
def restart_real_live(): """ 事件循環實現自動重啟 :return: """ qApp->exit(1207); # 因為 QCoreApplication::exec() 進入主事件循環,並等待直到調用exit(),返回傳遞給值exit(),所以可以在這上面動一下 if __name__=="__main__": current_exit_code = 1207 while current_exit_code == 1207: app = QApplication(sys.argv) main_window = MainWindow() main_window.show() run_state_mgr() current_exit_code = sys.exit(app.exec_()) main_window = None
最近在寫一個開源項目,需要實現一個程序自動重啟的功能。嘗試了好幾種方式,效果均不太理想。
一開始的實現思路是,記為思路一吧。大概就是寫一些 shell 腳本,然后在需要自動重啟的地方關閉當前程序,然后開一個進程執行這個 shell 腳本。
先來說一說這個關閉吧,主要的方法有:
QCoreApplication::exec()
// 進入主事件循環,並等待直到調用exit(),返回傳遞給值exit()。必須調用此函數來開始事件處理。主事件循環從窗口系統接收事件,並將事件分派給應用程序小部件。
QCoreApplication::exit(0);
// 告訴應用程序退出並返回代碼。調用此函數后,應用程序將離開主事件循環,並從調用返回至exec()。該EXEC()函數返回返回碼。如果事件循環未運行,則此功能不執行任何操作。
// 按照慣例,returnCode為0表示成功,並且任何非零值都表示錯誤。QApplication::exit(0);等價於它。
QCoreApplication::quit();
// 告訴應用程序退出,返回碼為0(成功)。等效於調用QCoreApplication::exit(0); QApplication::quit();等價於它。
close();
// QApplicatio有個常用屬性qApp->quitOnLastWindowClosed(true),當最后一個窗口關閉時自動調用前面的exit()。
QApplication::closeAllWindows();
// 關閉多個窗口,比調用quit好,因為窗口可以接受到 close 事件。
接着來說思路一:關閉之后,然后開一個進程執行這個 shell 腳本。發現舊應用沒有自動關閉,並且也啟動了新應用,關閉舊應用發現新應用也同時關閉。之后分析原因之后發現,因為使用的是 Python 的 multiprocessing 模塊提供的一個Process類來代表一個進程,此時新舊應用兩個之間是存在父子關系的,所以才會造成這種結果。
實現#
走了上面的坑了后,查看官方文檔可以知道,Qt 中常用的實現重啟的方式有兩種:
- 進程控制:即退出當前進程,再通過 QProcess 啟動一個新的進程。
- 事件循環:退出應用程序,然后通過 Application 事件循環控制程序啟動。
進程控制#
def restart_real_live():
""" 進程控制實現自動重啟 :return: """
qApp.quit()
# QProcess 類的作用是啟動一個外部的程序並與之交互,並且沒有父子關系。
p = QProcess
# applicationFilePath() 返回應用程序可執行文件的文件路徑
p.startDetached(qApp.applicationFilePath())
事件循環#
def restart_real_live():
""" 事件循環實現自動重啟 :return: """
qApp->exit(1207);
# 因為 QCoreApplication::exec() 進入主事件循環,並等待直到調用exit(),返回傳遞給值exit(),所以可以在這上面動一下
if __name__=="__main__":
current_exit_code = 1207
while current_exit_code == 1207:
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
run_state_mgr()
current_exit_code = sys.exit(app.exec_())
main_window = None