如何在PyQt中正确执行多进程?

9

我创建了一个按钮,当我点击按钮时,尝试运行多进程,但是UI被阻塞了。我希望进程在后台运行。

我该如何解决这个问题?

from PySide2 import QtCore,QtGui,QtWidgets
import sys
import multiprocessing
from threading import Timer
class TTT(multiprocessing.Process):
    def __init__(self):
        super(TTT, self).__init__()
        self.daemon = True
    def run(self):
        while True:
            t = Timer(5, self.doSomething)
            t.start()
            t.join()

    def doSomething(self):
        try:
            print('123')
        except Exception as e:
            print(e)

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        btn = QtWidgets.QPushButton('run process')
        btn.clicked.connect(self.create_process)
        self.setCentralWidget(btn)

    def create_process(self):
        QtWidgets.QMessageBox.information(self,'hhh','hhh')
        t = TTT()
        t.start()
        t.join()

if __name__=="__main__":
    app=QtWidgets.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

如果您使用Qt框架,我建议您使用Qt功能来完成此操作,而不是混合使用Qt和标准Python。在Qt中,信号和线程对我来说似乎非常棒 :) - Erik Šťastný
你的意思是使用 QThread 吗? - Relax ZeroC
QThread只是其中的一个选项。 - Erik Šťastný
如果我仍然想要使用多进程来解决这个问题,我该怎么做? - Relax ZeroC
我没有完全理解你对代码的期望。为什么要使用“while True”来创建计时器?你能提供具体的期望结果吗? - Erik Šťastný
3个回答

6

本文的主要问题已经由Bendegúz Szatmári回答。

我只是想让您知道,在大多数情况下,使用Process并不是最好的选择。 不同进程不会与您的程序共享内存。与不同线程相比,您无法轻松地控制它们。

以下是一个简单的示例,说明如何启动和停止不同的线程。

from PyQt5 import QtWidgets
from PyQt5.QtCore import *
import sys
import time


class TTT(QThread):
    def __init__(self):
        super(TTT, self).__init__()
        self.quit_flag = False

    def run(self):
        while True:
            if not self.quit_flag:
                self.doSomething()
                time.sleep(1)
            else:
                break

        self.quit()
        self.wait()

    def doSomething(self):
        print('123')


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.btn = QtWidgets.QPushButton('run process')
        self.btn.clicked.connect(self.create_process)
        self.setCentralWidget(self.btn)

    def create_process(self):
        if self.btn.text() == "run process":
            print("Started")
            self.btn.setText("stop process")
            self.t = TTT()
            self.t.start()
        else:
            self.t.quit_flag = True
            print("Stop sent")
            self.t.wait()
            print("Stopped")
            self.btn.setText("run process")


if __name__=="__main__":
    app=QtWidgets.QApplication(sys.argv)
    ex = MainWindow()
    ex.show()
    sys.exit(app.exec_())

2
非常好,非常感谢 @Erik Šťastný!但我的原因是我有一个CPU密集型任务,所以我认为我应该使用多进程。 - Relax ZeroC
@RelaxZeroC 请看这个链接:https://dev59.com/_3RB5IYBdhLWcg3wc280。我从事硬件、慢速闪存等工作,即使某些函数需要30秒才能完成,我也从未被迫使用不同的进程而不是简单的工作线程。 - Erik Šťastný
不错的例子,但没有多进程,如果在启动QThread后关闭主GUI,则线程不会被终止。 - pippo1980

3

我从来没有使用过multiprocessing,但文档说join()方法会阻塞调用者直到它完成。把这个方法放在一个无限循环中会永远阻塞调用者(UI)。


1
我在你之后几秒钟写的 :) 是的,在你的例子中进程从未终止,你一直在等待终止。 - Erik Šťastný
@Relax ZeroC,顺便说一下,像我之前所说的那样,检查QThreads的用法。使用不同的进程很痛苦。你没有共享内存,不能简单地在TTT中更改变量等。 - Erik Šťastný

1

这是与PyQt相关的编程内容,可能会有所帮助。以下是实际代码示例链接:https://medium.com/@sampsa.riikonen/doing-python-multiprocessing-the-right-way-a54c1880e300 - El Sampsa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接