PyGTK: Button Klick verhalten und Prozesse

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Dienstag 18. März 2008, 00:14

Hallo zusammen,

ich habe da ein Problem wo ich jetzt schon seit 4 Stunden einfach nicht so richtig eine Lösung zu finde. Es ist auch nicht einfach zu erklären ich hoffe aber es gelingt mir so das ihr es verstehen könnt.

Also ich habe auf einer Oberfläche einen Button und eine Progressbar. Soweit so gut :lol: (natürlich sind noch mehr dinge vorhanden aber es geht um das zusammenspiel der beiden). Sobald der Button gedrückt wird startet eine Suchanfrage im Internet. Nun habe ich mir überlegt das es ja ganz nett wäre wenn man eine kleine Progressbar einbaut die Pulsed solange die Suchanfrage dauert.

So und nun kommts....... Das Problem ist das wenn ich den Button drücke bleibt dieser gedrückt weil ja die Suchanfrage noch arbeitet und das Pulsen startet auch erst danach wenn der Button wieder loslässt aber dann ist ja der eigentliche Gag vorbei. Dann soll die Bar ja gar nicht mehr Pulsen.

Hier mal ein bisschen Beispiel Code ist aber wirklich nur Pseudo damit ihr ein bisschen ein Bild davon bekommt.

def on_click_search:
pulsen
suchanfrage
pulsen ende

Ich habe schon verschiedenste varianten probiert die PyGtk her gibt. Die da wären.

gobject.timeout(), gobject.idle_add; gtk.gdk.threads_enter() u. leave()

und Python os.fork() <- führt aber in schwere Fehler

Also wie gesagt ich will das das Pulsen nur solange läuft wie die Suchanfrage dauert.

Kann mir vielleicht jemand dabei helfen ..... sonst lass ich den Effekt einfach weg wenn das nicht möglich ist.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 18. März 2008, 10:48

Mit ``gobject.idle_add`` eine die Suche starten und die Progressbar auf pulsierend stellen. Wenn die Funktion die die Suche ausführt fertig ist, von dieser die Progressbar zurückstellen lassen.

Edit: Thread verschoben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Dienstag 18. März 2008, 11:34

Ich habe in meinen gtk helpern die folgende Funktion:

Code: Alles auswählen

def gtk_yield():
    """process all the peding events in the mainloop"""
    while gtk.events_pending():
         gtk.main_iteration()
Versuch mal diese Funktion aufzurufen nach dem du die Progressbar auf pulsierend gesetzt hast. Könnte funktionieren. :wink:
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Dienstag 18. März 2008, 23:00

erst mal danke euch beiden für eure Antworten. Puhh ich bin froh das jemand das verstehen konnte was ich meine.... :lol:

Ok also ich versuche gerade mit deiner Funktion zu arbeiten veers. Aber leider funktioniert diese auch so das erst wenn die suche zu ende ist und der Button los lässt geht das Pulsieren los.

Hier mal der Code ausschnitt:

Code: Alles auswählen

def on_search(self, data):
		gobject.timeout_add(100,self.bar_searching)
		self.gtk_yield()
		text = self.search_entry.get_text() 
		self.aur.clear_information()        
		self.aur.search(text)
		
		if self.aur.is_package():          
			self.on_information()
		else:
			self.no_pack_dialog()
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Donnerstag 20. März 2008, 13:10

Veers könntest du mir vielleicht sagen ob du das so gemeint hast. Oder gibts es vielleicht noch eine andere Methode.

Gruß

Treehouse
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Donnerstag 20. März 2008, 15:17

Die `bar_searching`-Methode könnte eventuell noch solch einen `gtk_yield`-Aufruf vertragen. Prinzipiell eben überall dort, wo du die GUI veränderst und "blockierst", also nicht sofort zur gtk-Hauptschleife zurückspringst.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Donnerstag 20. März 2008, 15:54

Ok ich werde da heute abend mal ausprobieren und dann sage ich bescheid bin mal gespannt ob es daran gelegen hat.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Donnerstag 20. März 2008, 21:33

Hallo,

so ich habe die Funktion jetzt mal auch in die bar_searching Methode gesetzt. Aber leider klappt es so immer noch nicht. :(
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Donnerstag 20. März 2008, 22:20

Treehouse hat geschrieben:Aber leider klappt es so immer noch nicht.
Ohne Code ist das ein einziges Ratespiel.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Donnerstag 20. März 2008, 22:22

Das da oben ist der Code den der Button ausführt und die Bar hat diesen Code nichts dolles soll halt nur ein bisschen Pulsen.

Code: Alles auswählen

	def bar_searching(self):
		self.gtk_yield()
		self.progressbar.set_text('Searching...')
		self.progressbar.pulse()
		return True
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Donnerstag 20. März 2008, 22:27

Das ``self.gtk_yield()`` muss nach dem ``self.progressbar.pulse()`` stehen. Aber die `bar_searching`-Methode wird wahrscheinlich eh erst aufgerufen, nachdem die Suche bereits vorbei ist.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Donnerstag 20. März 2008, 22:44

Ja auch wenn ich es so schreibe wie du es sagst geht es leider nicht. Ich bastel schon die ganze Zeit mir nen Wolf wie ich das hinbekomme das es vorher läuft. Aber leider komme ich keinen Schritt weiter. Das einzige was geklappt hat war ein fork aber danach bekomme ich so schwere Fehler das das Programm unbrauchbar ist.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Freitag 21. März 2008, 19:40

Hat vielleicht noch irgend jemand eine Idee wie ich es anstellen könnte das es funktioniert?

Meine vermutung ist das ich irgendwie das Suchen und das Pulsen als Subprocess laufen lassen muss. So das der Button früher los läßt und das Pulsen überhaupt anzeigt.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Freitag 21. März 2008, 20:24

Deine `on_search`-Methode wird beim Klicken auf den Button von gtk aufgerufen. Solange jetzt diese Methode ausgeführt wird, reagiert gtk nicht auf Events, löst keine aus und zeichnet die GUI auch nicht neu. Das bedeutet auch, dass solange keine mit `gobject.timeout_add` registrierten Timeout-Funktionen aufgerufen werden, folglich deine `bar_searching`-Methode nie aufgerufen wird.

Du könntest die Suche in einen Thread auslagen, dabei ist aber zu beachten, dass die wenigstens GUI-Toolkits, und dazu gehört auch gtk, es mögen, wenn man mit mehr als einem Thread auf die GUI zugreift. Du müsstest also immer vom gleichen Thread aus auf die GUI zugreifen.
Treehouse
User
Beiträge: 39
Registriert: Freitag 14. Dezember 2007, 00:40

Freitag 21. März 2008, 20:37

Danke erst mal für deine Antwort. Vielleicht klingt das jetzt ja total doof aber wie macht man sowas? :oops:

Vielleicht kannst du mir ja ein kleines Beispiel geben
Antworten