2010-01-15 11 views
16

Sto scrivendo un programma GUI usando PyQt4. C'è un pulsante nella mia finestra principale e facendo clic su questo pulsante. Spero di avviare un processo in background che è un'istanza di una classe derivata da processing.Process.problema di multiprocessing [pyqt, py2exe]

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

    def run(self): 
     ... 

(Si noti che sto usando la porta Python2.5 del pitone-multiprocessing ottenuto da http://code.google.com/p/python-multiprocessing/ è per questo che è processing.Process invece di multiprocessing.Process. Credo che questo dovrebbe non fare la differenza. ho ragione?)

il codice collegato al segnale pulsante di scatto è qualcosa di semplicemente come

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

Il programma funziona come previsto nell'interprete python, ovvero se è avviato dalla riga di comando "python myapp.py".

Tuttavia, dopo aver confezionare il programma utilizzando py2exe, ogni volta quando si fa clic su tale pulsante, invece di iniziare l'attività in background, una copia della finestra principale si apre. Non sono sicuro che quale sia la ragione di questo comportamento. Credo è legato alla seguente nota indirizzata a http://docs.python.org/library/multiprocessing.html#multiprocessing-programming

"funzionalità all'interno di questo pacchetto richiede che il principale metodo di essere importabili dai bambini. Questo è trattato nelle linee guida di programmazione tuttavia la pena sottolineare qui . Ciò significa che alcuni esempi, come gli esempi multiprocessing.Pool non funzioneranno nell'interprete interattivo "

l'unico posto che ho se nome ==" principale "è nel modulo principale come in un tipico programma di PyQt

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

Eventuali soluzioni su come risolvere questo problema? Grazie!

+0

Puoi chiarire: hai protetto il modulo principale come descritto nei documenti di multiprocessing? o non hai accesso al modulo principale (non so come funzioni pyqt)? vale anche la pena di verificare che stai usando l'ultima versione di py2exe. Ho avuto problemi in passato che si sono rivelati essere stati causati da obsoleto py2app/py2exe – James

+0

Grazie per il commento. Ho appena aggiunto la parte __name__ == "__main__" nel mio post. Non sono sicuro se sto proteggendo il modulo principale o no. L'ultima versione di py2exe che ho trovato da http://sourceforge.net/projects/py2exe/files/ è stata rilasciata il 2008-11-16 quindi penso di usare l'ultima versione di py2exe. –

risposta

26

Credo che il problema reale ha a che fare con questo:

Il programma funziona come previsto sotto l'interprete python, cioè se viene avviato dalla riga di comando "python myapp.py".

Tuttavia, dopo aver impacchettato il programma utilizzando py2exe, ogni volta che faccio clic su quel pulsante,> anziché avviare l'attività in background, viene visualizzata una copia della finestra principale.

è necessario aggiungere una chiamata speciale alla funzione freeze_support() per far funzionare il modulo multiprocessing con eseguibili "congelati" (ad esempio, quelli realizzati 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_() 

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

+1

+1: eseguito lo stesso identico problema qualche tempo fa, ha utilizzato la stessa identica soluzione. –

+1

Grazie mille. Funziona! Ero a conoscenza di questa funzione freeze_support() ma non l'ho inserita nel posto giusto. Invece di metterlo prima di a = QApplication (sys.argv), lo metto ogni volta prima che venga creata una nuova istanza di processo, il che sembra non funzionare. –

0

"Le funzionalità di questo pacchetto richiedono che il metodo principale sia utilizzabile dai bambini."

Penso che questo significhi che devi avere la funzione main() definita da qualche parte.

0

La domanda riguarda Python 2 ed è stata risolta. Per Python 3, sarebbe simile a:

from multiprocessing import freeze_support 

if __name__ == '__main__': 
    freeze_support() 

    a = QApplication(sys.argv) 
    ...