2010-01-15 10 views
16

Estoy escribiendo un programa de GUI usando PyQt4. Hay un botón en mi ventana principal y haciendo clic en este botón. Espero iniciar un proceso en segundo plano que es una instancia de una clase derivada del procesamiento.Proceso.problema de multiprocesamiento [pyqt, py2exe]

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

    def run(self): 
     ... 

(Tenga en cuenta que estoy usando el puerto python2.5 del pitón-multiprocesamiento obtenido de http://code.google.com/p/python-multiprocessing/ es por eso que es processing.Process en lugar de multiprocessing.Process. supongo que esto debería no hacer una diferencia. Estoy en lo cierto?)

el código conectado a la señal de clic de botón es algo simplemente como

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

El programa funciona como se esperaba bajo el intepreter de python, es decir, si se inicia desde la línea de comando "python myapp.py".

Sin embargo, después de empaquetar el programa usando py2exe, cada vez que al hacer clic en ese botón, en lugar de iniciar la tarea en segundo plano, una copia de la ventana principal aparece. No estoy seguro de cuál es el motivo de este comportamiento. Supongo que se relaciona con la siguiente nota dirigida en http://docs.python.org/library/multiprocessing.html#multiprocessing-programming

"Funcionalidad dentro de este paquete requiere que el principal método de ser importable por los niños. Esto se explica en las directrices de programación sin embargo, vale la pena señalar aquí . Esto significa que algunos ejemplos, como los ejemplos multiprocessing.Pool no funcionarán en el intérprete interactivo "

el único lugar que tengo si nombre ==" principal "se encuentra en el módulo principal como en un programa típico pyqt

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

Cualquier solución sobre cómo solucionar este problema? ¡Gracias!

+0

Puede aclarar: ¿ha protegido el módulo principal como se describe en los documentos de multiprocesamiento? o no tienes acceso al módulo principal (no sé cómo funciona pyqt)? también vale la pena comprobar que está utilizando la última versión de py2exe. He tenido problemas en el pasado que resultaron causados ​​por la fecha de vencimiento py2app/py2exe – James

+0

Gracias por el comentario. Acabo de agregar la parte __name__ == "__main__" en mi publicación. No estoy seguro de si estoy protegiendo el módulo principal o no. La última versión de py2exe que encontré en http://sourceforge.net/projects/py2exe/files/ fue lanzada el 11-11-2011 así que creo que estoy usando la última versión de py2exe. –

Respuesta

26

Creo que su problema actual tiene que ver con esto:

El programa funciona como se esperaba bajo el intepreter pitón, es decir, si se inicia desde la línea de comandos "myapp.py pitón".

Sin embargo, después de empaquetar el programa utilizando py2exe, cada vez que hago clic en ese botón,> en lugar de iniciar la tarea en segundo plano, aparece una copia de la ventana principal.

es necesario agregar un llamado especial a la función freeze_support() para hacer que el multiprocesamiento trabajo del módulo con los ejecutables "congelados" (por ejemplo, los fabricados con 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_() 

Referencia: http://docs.python.org/library/multiprocessing.html#multiprocessing.freeze_support

+1

+1: se metió en el mismo problema hace algún tiempo, utilizó exactamente la misma solución. –

+1

Muchas gracias. ¡Funciona! Conocía esta función freeze_support() pero no la puse en el lugar correcto. En lugar de ponerlo antes de a = QApplication (sys.argv), lo puse todo antes de que se cree una nueva instancia de proceso, lo que parece que no funciona. –

0

"La funcionalidad dentro de este paquete requiere que el método principal sea importable para los niños".

Creo que esto significa que tiene que tener la función main() definida en alguna parte.

0

La pregunta es sobre Python 2 y se resolvió. Para Python 3, se vería así:

from multiprocessing import freeze_support 

if __name__ == '__main__': 
    freeze_support() 

    a = QApplication(sys.argv) 
    ...