多进程问题 [pyqt, py2exe]

18 投票
3 回答
7676 浏览
提问于 2025-04-15 18:04

我正在用PyQt4写一个图形界面程序。我的主窗口里有一个按钮,点击这个按钮后,我希望能启动一个后台进程,这个进程是从processing.Process类派生出来的一个实例。

class BackgroundTask(processing.Process):
    def __init__(self, input):
        processing.Process.__init__(self)
        ...

    def run(self):
        ...

(注意,我使用的是python-multiprocessing的Python 2.5版本,来自http://code.google.com/p/python-multiprocessing/,所以用的是processing.Process而不是multiprocessing.Process。我想这应该没什么区别,对吧?)

与按钮点击信号相关的代码大概是这样的:

 processing.freezeSupport()
 task = BackgroundTask(input)
 task.start()

在Python解释器下,程序的运行效果是正常的,也就是说,如果从命令行用“python myapp.py”启动,它是可以正常工作的。

但是,当我用py2exe打包程序后,每次点击那个按钮时,不是启动后台任务,而是又弹出了一个主窗口。我不太确定这是为什么。我猜这和以下提到的内容有关,地址是http://docs.python.org/library/multiprocessing.html#multiprocessing-programming

“这个包里的功能要求方法能够被子进程导入。这在编程指南中有说明,但在这里提一下也是值得的。这意味着一些示例,比如multiprocessing.Pool的示例,在交互式解释器中是无法工作的。”

我只有在主模块里有name == "main",这和典型的pyqt程序是一样的。

if __name__ == "__main__":
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = MainWindow()
    w.show()
    a.exec_()

有没有解决这个问题的方法?谢谢!

3 个回答

0

这个问题是关于Python 2的,并且已经解决了。对于Python 3来说,代码看起来会是这样的:

from multiprocessing import freeze_support

if __name__ == '__main__':
    freeze_support()

    a = QApplication(sys.argv)
    ...
0

“这个包里的功能要求子类能够导入主方法。”

我觉得这句话的意思是,你需要在某个地方定义一个 main() 函数。

28

我觉得你遇到的实际问题是这样的:

这个程序在Python解释器下运行得很好,也就是说,如果你从命令行输入“python myapp.py”来启动它,程序是正常工作的。

但是,当我用py2exe打包这个程序后,每次点击那个按钮时,> 不是启动后台任务,而是弹出了主窗口的一个副本。

你需要添加一个特别的调用,使用freeze_support()函数,这样才能让多进程模块在“冻结”的可执行文件(比如用py2exe制作的)中正常工作:

if __name__ == "__main__":
    # add freeze support
    processing.freeze_support()
    a = QApplication(sys.argv)
    QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()"))
    w = MainWindow()
    w.show()
    a.exec_()

参考链接: http://docs.python.org/library/multiprocessing.html#multiprocessing.freeze_support

撰写回答