本文介绍了向 QApplication 发送信号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在向 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.

例如

  1. 我将 QApplication 作为子进程启动
  2. 我发送了一个 signal.CTRL_BREAK_EVENT(来自启动子进程的服务器).
  3. 什么也没发生.
  4. 我点击了 QApplication 中的任何按钮.
  5. 它处理signal.CTRL_BREAK_EVENT 并退出.
  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.

我当然希望第 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 发送信号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-05 07:13