我有一个基于 PyQt5 的应用程序,它在 Windows 上运行。我有一个主 GUI 进程,从中启动另一个运行工作函数的进程。我希望在主进程的工作进程中引发键盘中断。这可能吗?请参阅下面的代码片段以了解我正在尝试的内容。当我用简单的控制台界面替换 PyQt 部分时,这是有效的。不过我想让它与 GUI 一起工作。理想情况下,每次单击按钮时,工作线程都会打印计数器的值。
import multiprocessing as mp
from PyQt5.QtWidgets import *
def worker():
ctr = 0
for i in range(100):
try:
while True:
ctr += 1
except KeyboardInterrupt:
print(ctr)
def on_button_clicked():
#This raises a Keyorad Interrupt in the main process.
#It should somehow raise it in the worker process
raise KeyboardInterrupt
if __name__ == '__main__':
mp.freeze_support()
proc = mp.Process(target=worker)
proc.start()
app = QApplication([])
button = QPushButton('Click')
button.clicked.connect(on_button_clicked)
button.show()
app.exec()
为此,您首先必须将工作线程封装在派生自 QThread、QProcess 或 multiprocessing.Process/Thread 的类中。该课程需要一个包含您实际工作的公共
run
函数。
如果您使用 QThread/QProcess ,那么您的类需要一个额外的公共插槽,该插槽连接到单击 GUI 中的按钮时发出的信号。
如果您使用Python本机多处理模块中的进程/线程,那么您不需要插槽/信号,并且可以使用单击按钮时调用的简单附加公共函数。
当您的工作人员太忙而无法实际检查内部消息队列时,这两种方式都可能会变得棘手。即使是键盘中断也只有在有时间的情况下才会被处理(比如计算中的一个小中断)。
因此,在使用 Qt 的伪代码中,它看起来如下所示:
class worker(QThread):
def __init__(self):
super().__init__()
# your init stuff here
def run(self):
# your calculation here with an interrupt "toggle variable"
@pyqtSlot(str)
def key_interrupt(self, value):
print(value) # the pressed key
# change your toogle variable here, when you want to stop your calc
class myApp(QApplication):
key_press = Signal(str)
def __init__(self):
# your gui definition here
my_worker = worker()
button.clicked.connect(self.button_clicked)
self.key_press[str].connect(my_worker.key_interrupt)
my_worker.run()
def button_clicked(self):
key_press.emit(key_char)
您可以直接将
button.clicked
^ 信号连接到工作线程的 key_interrupt
插槽。但我不确定如何以这种方式传输密钥字符。
当您不熟悉插槽和信号时,还应该查看 Qt 文档:Docu