Seite 1 von 3

gobject idle funktioniert nicht so richtig

Verfasst: Samstag 31. Januar 2009, 12:06
von gugugs
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

Verfasst: Samstag 31. Januar 2009, 12:56
von veers
Das ist das erwartete verhalten. Die Funktion läuft im Mainloop, und blockt diesen so lange bis sie fertig ist. :wink:

- Jonas

Re: gobject idle funktioniert nicht so richtig

Verfasst: Samstag 31. Januar 2009, 13:22
von Leonidas
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.

Verfasst: Samstag 31. Januar 2009, 13:34
von gugugs
Jetzt mal abgesehen von der unordentlichkeit vom Code, wie kann ich das ambesten ändern, das es nicht im mainloop läuft?

Verfasst: Samstag 31. Januar 2009, 13:39
von Leonidas
Die Funktion in einem eigenen Thread oder Prozess starten. Die Stdlib hat Unterstützung für beides am Bord.

Verfasst: Samstag 31. Januar 2009, 15:13
von gugugs
Aber das verstehe ich nicht ganz, gobject.idle, ist doch im Prinzip so ein Art Thread für GTK?

Verfasst: Samstag 31. Januar 2009, 15:25
von 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.

Verfasst: Samstag 31. Januar 2009, 15:28
von gugugs
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?

Verfasst: Samstag 31. Januar 2009, 15:59
von numerix
gugugs hat geschrieben:Wie kann ich denn überhaupt eine Funktion an einen Thread geben? Geht das überhaupt?
http://docs.python.org/library/threading.html

Verfasst: Samstag 31. Januar 2009, 16:57
von gugugs
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?

Verfasst: Samstag 31. Januar 2009, 16:58
von Leonidas
gugugs hat geschrieben:ist das überhaupt von Bedeutung für mich?
Nein, ist es nicht.

Verfasst: Samstag 31. Januar 2009, 16:59
von gugugs
Wäre vllt jemand so nett mir auf die Sprünge zu helfen?^^

Verfasst: Samstag 31. Januar 2009, 17:07
von Leonidas
Schon mal überlegt die Suchfunktion zu verwenden? Dort steht nämlich durchaus schon ein Beispiel für GTK & Threads.

Verfasst: Samstag 31. Januar 2009, 17:16
von gugugs
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?

Verfasst: Samstag 31. Januar 2009, 17:24
von Leonidas
Sie ganz normal aufrufen?

Verfasst: Samstag 31. Januar 2009, 17:33
von gugugs
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.

Verfasst: Samstag 31. Januar 2009, 17:35
von Trundle
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.

Verfasst: Samstag 31. Januar 2009, 17:36
von numerix
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.

Verfasst: Samstag 31. Januar 2009, 17:36
von Leonidas
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.

Verfasst: Samstag 31. Januar 2009, 17:43
von gugugs
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