向QApplication发送信号

时间:2018-02-08 14:36:21

标签: python qt subprocess pyqt5 qapplication

我将signal.CTRL_BREAK_EVENT发送到QApplication子进程,并且子进程的处理程序设法捕获信号(并在退出之前执行一些魔术)。但是,当信号发送时,它才会被处理,直到我与QApplication窗口交互(导致它以某种方式使用CPU周期LOL),然后它才会处理信号。

E.g。

  1. 我将QApplication作为子流程启动
  2. 我发送了一个signal.CTRL_BREAK_EVENT(来自启动子进程的服务器)。
  3. 什么都没发生。
  4. 我点击了QApplication中的任何按钮。
  5. 它处理signal.CTRL_BREAK_EVENT并退出。
  6. 我当然更喜欢步骤5在步骤3进行。

    出了什么问题?我将如何刷新"当QApplication在子进程中运行时,点击一个按钮?我怀疑QApplication的主事件循环以某种方式处于空闲模式......直到应用程序与之交互。 (?)

    server.py

    app = None
    
    def start_app():
        global app
    
        app = subprocess.Popen("python app.py")
    
    def exit_app():
        global app
    
        p = app.poll()
        if p==None:
            print("Subprocess is alive") # debug
        app.send_signal(signal.CTRL_BREAK_EVENT)
    

    app.py

    import sys, signal
    from runner import mainWindow
    
    from PyQt5.QtWidgets import QApplication
    
    app = None
    mw = None
    
    def exit_signal_handler(signal, frame):
        global app, mw
    
        print("Terminate signal received")
        app.quit()
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        signal.signal(signal.SIGBREAK, exit_signal_handler)
    
        mw = mainWindow.MainWindow() # this is the Qt window starting
        mw.actionExit.triggered.connect(app.quit)
    
        sys.exit("Runner exit with code: " + str(app.exec()))
    

1 个答案:

答案 0 :(得分:0)

出于民意调查原因在app.py中添加Qtimer()似乎可以解决问题。 pollMe()

调用Qtimer时,将每秒处理发送的任何信号
import sys, signal
from runner import mainWindow
from PyQt5 import QtCore           #<---- NEW
from PyQt5.QtWidgets import QApplication

app = None
mw = None

def pollMe():                      # <--- NEW
    timerPoll.start(1000)

def exit_signal_handler(signal, frame):
    global app, mw

    print("Terminate signal received")
    app.quit()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    signal.signal(signal.SIGBREAK, exit_signal_handler)

    timerPoll = QtCore.QTimer()        #<---- NEW
    timerPoll.timeout.connect(pollMe)
    timerPoll.start(1000)

    mw = mainWindow.MainWindow() # this is the Qt window starting
    mw.actionExit.triggered.connect(app.quit)

    sys.exit("Runner exit with code: " + str(app.exec()))