16

我正在使用 PyQt4 编写一个 GUI 程序。我的主窗口中有一个按钮,然后单击此按钮。我希望启动一个后台进程,它是从 processing.Process 派生的类的一个实例。

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

    def run(self):
        ...

(请注意,我使用的是从 http://code.google.com/p/python-multiprocessing/获得的 python-multiprocessing 的 Python2.5 端口, 这就是为什么它是 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_()

有关如何解决此问题的任何解决方案?谢谢!

4

3 回答 3

26

我认为您的实际问题与此有关:

该程序在 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

于 2010-02-04T00:52:34.107 回答
0

“这个包中的功能要求主要方法可以被孩子们导入。”

我认为这意味着您必须在某处定义 main() 函数。

于 2010-01-29T05:27:39.870 回答
0

这个问题是关于 Python 2 的并且已经解决了。对于 Python 3,它看起来像:

from multiprocessing import freeze_support

if __name__ == '__main__':
    freeze_support()

    a = QApplication(sys.argv)
    ...
于 2017-12-28T12:44:47.400 回答