Qt5/PyQt5 實現程序重啟的兩種方法


原文: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM