2010-01-15 11 views
16

Ich schreibe ein GUI-Programm mit PyQt4. Es gibt eine Schaltfläche in meinem Hauptfenster und durch Klicken auf diese Schaltfläche. Ich hoffe, einen Hintergrundprozess zu starten, der eine Instanz einer abgeleiteten Klasse von processing.Process ist.Multiprocessing-Problem [pyqt, py2exe]

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

    def run(self): 
     ... 

(Beachten Sie, dass ich die python2.5-Port erhalten der Python-Multiprozessing bin mit von http://code.google.com/p/python-multiprocessing/ Deshalb ist es processing.Process ist statt multiprocessing.Process. denke, ich sollte dies einen Unterschied machen, nicht. Habe ich recht?)

der Code auf die Schaltfläche Click-Signal verbunden ist etwas einfach wie

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

Das Programm funktioniert wie erwartet unter dem Python-Interpreter, d. H. , wenn es über die Befehlszeile "python myapp.py" gestartet wird.

jedoch, nachdem ich das Programm-Paket mit py2exe, jedes Mal, wenn ich auf diese Schaltfläche klicken, wird stattdessen die Hintergrundaufgabe starten, eine Kopie des Hauptfensters erscheint. Ich bin mir nicht sicher was ist der Grund für dieses Verhalten. Ich denke, wird es auf den folgenden Hinweis im Zusammenhang adressierte bei http://docs.python.org/library/multiprocessing.html#multiprocessing-programming

„Funktionalität innerhalb dieses Pakets erfordert, dass die Haupt Methode von den Kindern importierbar sein. Dies ist jedoch in Programmierrichtlinien abgedeckt es beachtenswert, hier Dies bedeutet. dass einige Beispiele, wie die multiprocessing.Pool Beispiele nicht im interaktiven Interpreter arbeiten „

der einzige Ort, den ich habe, wenn Name ==“ Haupt "im Hauptmodul wie in einem typischen pyqt Programm

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

Alle Lösungen, wie dieses Problem zu beheben? Vielen Dank!

+0

Können Sie klarstellen: Haben Sie das Hauptmodul wie in den Multiprocessing-Dokumenten beschrieben geschützt? oder hast du keinen Zugriff auf das Hauptmodul (ich weiß nicht, wie pyqt funktioniert)? Überprüfen Sie auch, ob Sie die neueste Version von py2exe verwenden. Ich hatte Probleme in der Vergangenheit, die sich durch veraltete py2app/py2exe verursacht wurden – James

+0

Vielen Dank für den Kommentar. Ich habe gerade den __name__ == "__main__" Teil in meinem Beitrag hinzugefügt. Nicht sicher, ob ich das Hauptmodul schütze oder nicht. Die neueste Version von py2exe, die ich von http://sourceforge.net/projects/py2exe/files/ gefunden habe, wurde am 2008-11-16 veröffentlicht. Daher denke ich, dass ich die neueste Version von py2exe verwende. –

Antwort

26

Ich denke, Ihr eigentliches Problem damit zu tun hat:

Das Programm arbeitet wie unter dem Python-Interpreter erwartet, das heißt, wenn es von der Kommandozeile „Python myapp.py“ gestartet wird.

Nachdem ich jedoch das Programm mit py2exe gepackt habe, erscheint jedes Mal, wenn ich auf diese Schaltfläche klicke,> anstatt die Hintergrundaufgabe zu starten, erscheint eine Kopie des Hauptfensters.

Sie benötigen einen speziellen Aufruf an die freeze_support() Funktion hinzuzufügen, um die Multiprocessing-Modul Arbeit mit "eingefroren" Executables zu machen (zB solche, die mit 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_() 

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

+1

+1: Habe vor einiger Zeit genau das selbe Problem gehabt, genau das gleiche Problem. –

+1

Vielen Dank. Es klappt! Ich war mir der Funktion freeze_support() bewusst, aber ich habe sie nicht an die richtige Stelle gesetzt. Anstatt es vor a = QApplication (sys.argv) zu setzen, lege ich es jedes Mal ab, bevor eine neue Prozessinstanz erstellt wird, was anscheinend nicht funktioniert. –

0

"Funktionalität in diesem Paket erfordert, dass die Hauptmethode von den Kindern importiert werden kann."

Ich denke, das bedeutet, Sie müssen main() -Funktion irgendwo definiert haben.

0

Die Frage bezieht sich auf Python 2 und wurde gelöst. Für Python 3 würde es wie folgt aussehen: