问题描述
我正在向 QApplication 子进程发送一个 signal.CTRL_BREAK_EVENT
并且子进程的处理程序设法捕获信号(并在退出之前执行一些魔术).然而,当信号被发送时,它不会被处理,直到我与 QApplication 窗口交互(导致它以某种方式使用 CPU 周期 LOL),只有这样它才会处理信号.
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.
例如
- 我将 QApplication 作为子进程启动
- 我发送了一个
signal.CTRL_BREAK_EVENT
(来自启动子进程的服务器). - 什么也没发生.
- 我点击了 QApplication 中的任何按钮.
- 它处理
signal.CTRL_BREAK_EVENT
并退出.
- I start QApplication as subprocess
- I send a
signal.CTRL_BREAK_EVENT
(from server that started the subprocess). - Nothing happens.
- I click on any button in the QApplication.
- It handles the
signal.CTRL_BREAK_EVENT
and exits.
我当然希望第 5 步发生在第 3 步.
I would of course prefer step 5 to take place at step 3.
怎么了?当 QApplication 在子进程中运行时,我将如何刷新"它或虚拟地单击按钮?我怀疑 QApplication 的主事件循环不知何故处于空闲模式......直到应用程序与之交互.(?)
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()))
推荐答案
出于投票原因在 app.py 中添加 Qtimer()
似乎可以解决问题.当 pollMe()
被 Qtimer
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()))
这篇关于向 QApplication 发送信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!