Seite 1 von 1

veränderten text in gtk.TextView-Element anzeigen

Verfasst: Sonntag 24. Juni 2012, 19:23
von Myra
Hi,
ich möchte in einer Funktion den Text eines gtk.TextView - Elements ändern,
den neuen Text kurz anzeigen lassen
und dann nach einer kurzen Wartezeit den Text endgültig ändern.

Was ich nicht hinkriege, ist dass die erste Änderung auch angezeigt wird.
Die Anzeige wird erst aktualisiert wenn die 'Text-Änder-Funktion' sich beendet hat.

Hier mal etwas Source-Code um zu zeigen was ich meine:
es geht eigentlich nur um die kleine Funktion change_text():

Code: Alles auswählen

#!/usr/bin/env python

import pygtk
pygtk.require('2.0')
import gtk
import time

class TextViewExample:
    def change_text(self, widget):
        self.textbuffer.set_text("erster Text")
        """Jetzt soll der neue Text fuer eine Sekunde angezeigt werden, was aber NICHT funktioniert"""
        #self.sw.show()
        #self.textview.show()
        #self.window.show()
        time.sleep(1)
        """Jetzt wird der Text nochmal gaendert"""
        self.textbuffer.set_text("zweiter Text")

    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_resizable(True)  
        self.window.set_title("TextView Beispiel")
        self.window.set_border_width(0)
        box1 = gtk.VBox(False, 0)
        self.window.add(box1)
        box1.show()
        box2 = gtk.VBox(False, 10)
        box2.set_border_width(10)
        box1.pack_start(box2, True, True, 0)
        box2.show()
        self.sw = gtk.ScrolledWindow()
        self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.textview = gtk.TextView()
        self.textbuffer = self.textview.get_buffer()
        self.sw.add(self.textview)
        self.sw.show()
        self.textview.show()
        box2.pack_start(self.sw)
        hbox = gtk.HButtonBox()
        box2.pack_start(hbox, False, False, 0)
        hbox.show()
        vbox = gtk.VBox()
        vbox.show()
        hbox.pack_start(vbox, False, False, 0)
        button = gtk.Button("change text")
        button.connect("clicked", self.change_text)
        box2.pack_start(button, True, True, 0)
        button.set_flags(gtk.CAN_DEFAULT)
        button.grab_default()
        button.show()
        self.window.show()

def main():
    gtk.main()
    return 0       

if __name__ == "__main__":
    TextViewExample()
    main()
Würde mich freuen wenn mir da jemand helfen könnte.

Gruß
myra

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Sonntag 26. Januar 2014, 17:05
von martinjo
Hast du da mittlerweile eine Lösung bzw. die Ursache dafür gefunden?

button.connect("clicked", self.change_text)

Hier noch ma ein Beispiel, es wir nur der letzte "self.textbuffer.set_text" gesetzt.

Code: Alles auswählen

    def change_text(self, widget):
        self.textbuffer.set_text("erster Text")
        time.sleep(0.2)
        self.textbuffer.set_text("zweiter Text")
        time.sleep(0.2)
        self.textbuffer.set_text("aber nur ich werde angezeigt ")

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Sonntag 26. Januar 2014, 17:29
von BlackJack
@martinjo: Die GUI zeigt Veränderungen erst an wenn die GUI-Hauptschleife wieder die Kontrolle hat, also wenn die Methode zuende ist und dorthin zurück kehrt. Darum darf man in Methoden die von der Hauptschleife aufgerufen werden auch nichts machen was länger dauert, denn für die Laufzeit der Methode „friert” die GUI-Anzeige ein. GUI-Toolkits haben für den hier gewünschten Fall üblicherweise eine Methode um Funktionen oder Methoden zeitverzögert aufrufen zu lassen. Vorgehensweise wäre also den Text zu ändern und eine Funktion zu registrieren die 0,2s aufgerufen werden soll um den Text erneut zu ändern. Gtk hat dafür die `timeout_add()`-Funktion (Name ist anhand des Namens der Funktion in der `libglib` geraten).

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Montag 27. Januar 2014, 14:16
von martinjo
Danke :D

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Donnerstag 30. Januar 2014, 16:46
von diesch
Wenn der Benutzer innerhalb der Wartezeit nicht mit der GUI arbeiten können muss, reicht es, vor der Pause

Code: Alles auswählen

while Gtk.events_pending():
    Gtk.main_iteration()
aufzurufen.

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Donnerstag 30. Januar 2014, 17:06
von BlackJack
@diesch: Dann funktioniert aber die komplette GUI- und Ereignisverwaltung während der Wartezeit nicht. Das Fenster wird nicht neu gezeichnet wenn irgend etwas darüber gezeichnet wurde, zum Beispiel Benachrichtigungen oder bei bestimmten Systemen kann selbst der Mauszeiger ”Spuren” im Fenster hinterlassen. Und wenn das Programm die Ereignisverwaltung zum Beispiel auch für I/O-Aufgaben verwendet, dann werden die auch so lange blockiert.

Re: veränderten text in gtk.TextView-Element anzeigen

Verfasst: Donnerstag 30. Januar 2014, 17:51
von diesch
Ja. Ob das akzeptabel oder sogar erwünscht ist, hängt vom Programm ab.

Mit GLib.timeout_add kann der Code unübersichtlicher und fehleranfälliger werden, weil es schwerer nachzuvollziehen ist, in welcher Reihenfolge Dinge passieren.