Sending signal to QApplication

血红的双手。 提交于 2019-12-14 04:11:15

问题


I'm sending a signal.CTRL_BREAK_EVENT to a QApplication subprocess and the subprocess's handler manages to catch the signal (and perform some magic before exiting). However, when the signal is sent, it is not processed until I interact with the QApplication window (causing it to somehow use CPU cycles LOL), only then will it handle the signal.

E.g.

  1. I start QApplication as subprocess
  2. I send a signal.CTRL_BREAK_EVENT (from server that started the subprocess).
  3. Nothing happens.
  4. I click on any button in the QApplication.
  5. It handles the signal.CTRL_BREAK_EVENT and exits.

I would of course prefer step 5 to take place at step 3.

What's wrong? How would I "refresh" the QApplication or virtualy click a button when it's run in a subprocess? I suspect that the QApplication's main event loop somehow is in idle mode... until the application is interacted with. (?)

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:


Adding a Qtimer() in app.py for poll reasons seems to do the trick. Any signals sent will be processed every second when pollMe()is called by 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()))


来源:https://stackoverflow.com/questions/48687981/sending-signal-to-qapplication

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!