Seite 1 von 1

Problem mit Zugriff auf vorherigen Prozess

Verfasst: Freitag 14. September 2007, 13:03
von Stolzi
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

Re: Problem mit Zugriff auf vorherigen Prozess

Verfasst: Freitag 14. September 2007, 13:16
von gerold
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
:-)

Verfasst: Freitag 14. September 2007, 14:35
von Stolzi
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?

Verfasst: Freitag 14. September 2007, 15:23
von gerold
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
:-)

Verfasst: Freitag 14. September 2007, 15:38
von Stolzi
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

Verfasst: Freitag 14. September 2007, 16:08
von gerold
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
:-)

Verfasst: Freitag 14. September 2007, 18:32
von Stolzi
Arg... das wars ;-) Danke dir, jetzt funzt alles prächtig!