Problem mit Zugriff auf vorherigen Prozess

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Hallo,

ich versuche das Skript kurz zu erklären, da es schwierig wäre etwas ähnliches als Beispiel zu geben:
Ich habe in meinem Thread eine Klasse die ein wxpython Fenster erzeugt. Diese ruft auf Knopfdruck eine andere Klasse auf, die eine ihrer Funktionen mehrmals startet mit:

Code: Alles auswählen

thread.start_new_thread(Funktion,(Arg1,Arg2))
Nun wollte ich eine Rückmeldung an das Fenster schicken sobald der letzte Thread durch ist. Dazu rufe ich vom letzten Thread aus eine Funktion in der ursprünglichen Klasse mit dem Fenster auf. Manchmal gehts, aber meist kommt der Fehler:

Code: Alles auswählen

Xlib: unexpected async reply (sequence 0x45a1)!
Wie muss ich denn das korrekt machen wenn ich von einem Thread etwas zurück geben will?

Ich habe das von gerold hier schon gefunden:
Das ist schwieriger als man glaubt. Es ist wichtig, dass wxPython nur in **einem** Thread läuft. Also muss das Initialisieren der wxPySimpleApp im gleichen Thread laufen wie später die MainLoop. An der MainLoop blockiert wxPython so lange, bis ein wxPython-Event ausgelöst wird.
Aber ich verstehe dennoch nicht wie der Thread dann eine Funktion im alten ausführen kann. Oder muss der alte irgendwie den neuen überwachen?
Hab speziell dazu nix gefunden im Forum :-/

Danke
Stolzi
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Stolzi hat geschrieben:mehreren Prozessen
[...]
thread.start_new_thread
[...]
Nun wollte ich eine Rückmeldung an das Fenster schicken
Hallo Stolzi!

1.) Prozess oder Thread?

2.) Kurze Antwort: wx.CallAfter() verwenden. Lange Antwort(en):
- http://www.python-forum.de/post-48365.html#48365
- http://www.python-forum.de/post-42785.html#42785
- http://www.python-forum.de/post-35412.html#35412

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Ahh danke, dann wär das doch für mein Prob auch gewesen. Ich werd mal spielen. Viell noch kurz als Info: Funktioniert das auch wenn der wxpython Thread einen Thread gestartet hat, der dann wiederum einen Thread startet und dieser ruft dann CallAfter auf?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Stolzi hat geschrieben:Funktioniert das auch wenn der wxpython Thread einen Thread gestartet hat, der dann wiederum einen Thread startet und dieser ruft dann CallAfter auf?
Hallo Stolzi!

Ich glaube schon. Du musst nur immer darauf achten, dass die GUI-Ausgabe *nur* in dem Thread passiert, in dem auch die App erstellt wurde. Und mit wx.CallAfter übergibst du an diesen Thread, was zu tun ist sobald es die Programmschleife (MainLoop) wieder erlaubt.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

MMMM geht noch nicht so wie ich will.

Ich habe in der Klasse die den Frame erzeugt (MyFrame) eine Funktion die mir Rückmeldungen in mein

Code: Alles auswählen

self.t3 = wx.TextCtrl(self, -1,"Ergebnisse:\n",size=(600, 150),style=wx.TE_MULTILINE)
schreibt:

Code: Alles auswählen

 
def InfoText(self,text):
    self.t3.AppendText(text+"\n")
Wenn ich nun den gestarteten Thread mit

Code: Alles auswählen

wx.CallAfter(self.parent.InfoText,"Fertiggestellt")
direkt da reinschreiben lasse funzts.
Rufe ich jedoch (wie ich es gerne möchte) in der Klasse MyFrame die Funktion:

Code: Alles auswählen

def Done(self):
    print "Enable"
    self.Enable()
    print "Sende fertig Info"
    self.InfoText("+++++++++++++FERTIG++++++++++++++++")
mit:

Code: Alles auswählen

wx.CallAfter(self.parent.Done())
in dem Thread auf, dann bekomme ich folgenden Fehler und der Frame ist irgendwie abgestürzt (im TextCtrl steht nix mehr, ein Button ist verschwunden...):

Code: Alles auswählen

Enable
Sende fertig Info
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/wx-2.6-gtk2-unicode/wx/_core.py", line 13465, in <lambda>
    lambda event: event.callable(*event.args, **event.kw) )
TypeError: 'NoneType' object is not callable
Du siehst... Print gibt noch alles schön aus und dann kommen die Fehler.

Weisst du da Rat?

Danke
Stolzi
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Stolzi hat geschrieben:

Code: Alles auswählen

wx.CallAfter(self.parent.Done())
Hallo Stolzi!

Code: Alles auswählen

wx.CallAfter(self.parent.Done)
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Arg... das wars ;-) Danke dir, jetzt funzt alles prächtig!
Antworten