gobject idle funktioniert nicht so richtig

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

ich hab folgende recht komplexe Abfolge von Funktionen

Code: Alles auswählen

	#upload idle
	def upload_idle(self, data=None):
		current_ftp_dir=self.ftp_connect.pwd()
		sel_rows=self.homecallback()
		for r in sel_rows:
			dir=os.path.join(self.homedirname, r)
			filestat=os.stat(dir)
			if stat.S_ISDIR(filestat.st_mode):
				for root, dirs, files in os.walk(dir):
					self.ftp_connect.sendcmd("MKD %s" % os.path.split(root)[1])
					self.ftp_connect.sendcmd("CWD %s" % os.path.split(root)[1])
					if files:
						for f in files:
							file=f
							file_path=os.path.join(root, f)
							f_open=open(file_path, "r") 
							self.ftp_connect.storbinary("STOR %s" % file, f_open) 
							f_open.close()
				self.ftp_connect.cwd(current_ftp_dir)
				self.ftpmake_list()
			else:
				file=os.path.split(dir)[1]
				file_path=dir
				f_open=open(file_path, "r") 
				self.ftp_connect.storbinary("STOR %s" % file, f_open) 
				f_open.close()
				self.ftp_connect.cwd(current_ftp_dir)
				self.ftpmake_list()
		gobject.source_remove(self.timer)
		return
		
	#Progress Timeout
	def progress_timeout(self, progress):
		progress.pulse()
		return True
	
	#Upload Datein
	def on_upload_clicked(self, widget):
		#self.timer=gobject.timeout_add(50, self.progress_timeout, self.progressbar2)
		gobject.idle_add(self.upload_idle, "nothing")
		print "ka"
der timer ist erst mal auskomentiert, da er erst mal unwichtig ist, das problem ist, das das gobjectidle nicht so funktioniert. Wenn ich den Knopf aktiviere, dann arbeitet er zwar die Funktion ab, aber mein Knopf bleibt gedürckt, also mein Programm ist in der Zeit eingefroren. Weiß jemand an was es liegen könnte?

edit: manches ist ein bisschen sinnlos, z.b. das data=None und "nothing" aber ich hatte mal alles mögliche getestet um mein problem zu beheben
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Das ist das erwartete verhalten. Die Funktion läuft im Mainloop, und blockt diesen so lange bis sie fertig ist. :wink:

- Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:edit: manches ist ein bisschen sinnlos, z.b. das data=None und "nothing" aber ich hatte mal alles mögliche getestet um mein problem zu beheben
Und der Code ist auch ansonsten recht fürchterlich. PEP8? Sinnvolle Namen? Builtins nicht überschreiben?

Und wie veers sagte: die Funktion block die ganze Mainloop. Heißt also nicht nur dass der Button gedrückt bleibt, sondern dasss das Fenster nicht mehr neugezeichnet wird.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Jetzt mal abgesehen von der unordentlichkeit vom Code, wie kann ich das ambesten ändern, das es nicht im mainloop läuft?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Die Funktion in einem eigenen Thread oder Prozess starten. Die Stdlib hat Unterstützung für beides am Bord.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Aber das verstehe ich nicht ganz, gobject.idle, ist doch im Prinzip so ein Art Thread für GTK?
lunar

gugugs hat geschrieben:Aber das verstehe ich nicht ganz, gobject.idle, ist doch im Prinzip so ein Art Thread für GTK?
Ich kenne Gtk nicht, aber der Name legt nahe, dass gobject.idle eine Funktion zur Abarbeitung vorsieht, wenn sich die Ereignisschleife im Leerlauf befindet, der Aufruf der Funktion selbst aber aus dem Kontext der Ereignisschleife heraus erfolgt.

Anstatt also die Funktion sofort auszuführen, wird sie ausgeführt, sobald keine Ereignisse der Benutzeroberfläche mehr zur Bearbeitung anliegen. Bei einer einfachen Oberfläche dürfte das nach dem Zeichnen des Knopfs der Fall sein, so dass die Funktion scheinbar sofort ausgeführt wird. Allerdings läuft sie trotzdem innerhalb der Hauptschleife, die daher trotzdem blockiert.

Der Ablauf dürfte also der sein, dass sich die Ereignisschleife im Leerlauf befindet, daher deine Funktion ausführt, die entsprechend lange braucht, so dass die Ereignisschleife nicht weiterläuft, obwohl andere Ereignisse zur Bearbeitung anliegen.

Ein eigener Thread ist das auf jeden Fall nicht, das zeigt schon das beobachtete Verhalten.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ok, um das ganze aber mit einem Thread zu machen, ist es aber glaube ich ein bisschen umständlich, da ich bei einem Thread ja eine neue Klasse machen muss, aber in der Funktion die ich in den Thread packen will, wird viel benutzt, das in der hauptklasse definiert ist, alles was in den Thread zu übergeben ist denke ich ein bisschen umständlich, besonders, wenn es funktionen sind die benutzt werden.

Wie kann ich denn überhaupt eine Funktion an einen Thread geben? Geht das überhaupt?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

gugugs hat geschrieben:Wie kann ich denn überhaupt eine Funktion an einen Thread geben? Geht das überhaupt?
http://docs.python.org/library/threading.html
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Jetzt weiß ich immer noch nicht, wie ich es so lösen kann, das ich nicht alles von einer klasse zur thread klasse geben muss.

Was ist der Unterschied zwischen
threading.setprofile(func)
und
threading.settrace(func)?

und ist das überhaupt von Bedeutung für mich?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:ist das überhaupt von Bedeutung für mich?
Nein, ist es nicht.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Wäre vllt jemand so nett mir auf die Sprünge zu helfen?^^
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Schon mal überlegt die Suchfunktion zu verwenden? Dort steht nämlich durchaus schon ein Beispiel für GTK & Threads.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ja, aber so muss ich doch alles an die Thread klasse übergeben, wie in dem Beispiel das threadcount, aber wenn, jetzt z.b. in meinem Thread eine Funktion benötige, die nicht im Thread sondern auserhalb der Thread Klasse definiert ist, was mache ich dann?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sie ganz normal aufrufen?
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Ich kann wenn ich in einer Thread Klasse bin eine Funktion aufrufen, die in einer ganz anderen Klasse ist??? Mir sagt er dann, das es diese Funktion nicht gibt.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

gugugs hat geschrieben:Wäre vllt jemand so nett mir auf die Sprünge zu helfen?^^
[mod]threading[/mod] lesen, und zwar "Thread Objects". Was die Thread-Klasse so an Argumenten entgegen nimmt dürfte beispielsweise recht interessant für dich sein.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

gugugs hat geschrieben:Ich kann wenn ich in einer Thread Klasse bin eine Funktion aufrufen, die in einer ganz anderen Klasse ist??? Mir sagt er dann, das es diese Funktion nicht gibt.
Was genau "sagt er" denn? Das, was "er sagt", dürfte mit den Threads an sich wenig zu tun haben. Am besten zeigst du mal den entsprechenden Code und den Traceback.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gugugs hat geschrieben:Ich kann wenn ich in einer Thread Klasse bin eine Funktion aufrufen, die in einer ganz anderen Klasse ist??? Mir sagt er dann, das es diese Funktion nicht gibt.

Code: Alles auswählen

instanz = Klasse()
instanz.methode()
Das funktioniert auch in Threads. Ansonsten solltest du Code posten, denn deine Beschreibung führt nicht dazu, dass irgendetwas klarer wird. Eher im Gegenteil.
gugugs
User
Beiträge: 113
Registriert: Dienstag 30. Dezember 2008, 12:38

Hm, das ist leider vllt ein bisschen schlecht den ganzen Code zu posten, da dieser momentan 1000 Zeilen umfasst.

Aber jetzt nur mal als Theorie, ginge dieses Prinzip?:

klasse thread(threading.Thread)
funktion__init__(self)
threading.Thread.__init__(self)

funktion run(self)
self.eins anzeigen?
self.zwei anzeigen?

klasse programm
funktion __init__(self)
self.eins
self.zwei
self.drei
thread=thread
thread.start()



ginge das nach dem Prinzip so?

P.s.: Falls es einer vorher unvollständig gelesen hat, bin ausversehen zu früh auf senden gekommen
Antworten