2010-01-15 87 views
16

我在用PyQt4编写一个GUI程序。 我的主窗口 中有一个按钮,点击此按钮。 我希望能够启动一个后台进程 ,这是来自processing.Process的派生类 的一个实例。多处理问题[pyqt,py2exe]

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

    def run(self): 
     ... 

(请注意,我用的是端口的python2.5获得 蟒蛇-多的 从 http://code.google.com/p/python-multiprocessing/ 这就是为什么它是processing.Process 而不是multiprocessing.Process。 我想这应该不有所作为。 我说得对不对?)

连接到按钮点击信号 的代码是什么单纯的喜欢

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

如果程序是从命令行“python myapp.py”启动的,该程序在python解释器下按预期工作,即 。

然而,当我使用py2exe, 每次打包程序,当我点击该按钮,而不是 启动后台任务,主窗口的副本 弹出。我不确定 这种行为的原因是什么。我想 它关系到下面的注释在 http://docs.python.org/library/multiprocessing.html#multiprocessing-programming

解决 “这个软件包内的功能要求主要方法是通过孩子们可导入,这是覆盖在编程指南然而,值得指出的是这里这意味着一些例子,比如multiprocessing.Pool例子不会在交互式解释工作 主要“是在主模块中“

只有我有,如果 ==地方” 在一个典型的pyqt程序

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

任何解决方案如何解决这个问题?谢谢!

+0

您能否澄清一下:您是否保护了多处理文档中描述的主模块?或者你没有访问主模块(我不知道pyqt是如何工作的)?还值得检查你使用的是最新版本的py2exe。过去我遇到过问题,原因是过时的py2app/py2exe – James 2010-01-15 19:07:34

+0

谢谢你的评论。我在我的文章中添加了__name__ ==“__main__”部分。不确定我是否保护主模块。我从http://sourceforge.net/projects/py2exe/files/找到的最新版py2exe在2008年11月16日发布,所以我认为我使用的是最新版本的py2exe。 – 2010-01-15 19:42:24

回答

26

我觉得您的实际问题与此有关:

该项目工程蟒蛇intepreter下不如预期,即如果在命令行“蟒蛇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

+1

+1:前段时间遇到完全相同的问题,使用完全相同的修复程序。 – 2010-02-04 00:58:25

+1

非常感谢。有用!我知道这个freeze_support()函数,但我没有把它放在正确的地方。我没有把它放在a = QApplication(sys.argv)之前,而是每次在创建一个新的流程实例之前都放过它,这似乎不起作用。 – 2010-02-05 15:47:55

0

“此包中的功能要求主要方法可由孩子导入。”

我想这意味着你必须在某处定义main()函数。

0

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

from multiprocessing import freeze_support 

if __name__ == '__main__': 
    freeze_support() 

    a = QApplication(sys.argv) 
    ...