Qt5/PyQt5 實現程式重啟的兩種方法
阿新 • • 發佈:2020-12-24
原文: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