gtk.ScrollWindow automatisch scrollen?

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Benutzeravatar
Cyber Mage
User
Beiträge: 5
Registriert: Samstag 2. Februar 2008, 10:48
Wohnort: Bremen
Kontaktdaten:

Hi liebe Python Community :)

Ich habe vor kurzem gefallen an Python gefunden und hab mich gleich dran gesetzt es ein bisschen zu lernen. Ich bin gerade dabei OOP und GUI (mit GTK+) zu lernen und bekomme das (nach meinen erachtens) gut hin.

Jetzt hab ich aber ein Problem dass ich trotz lesen vieler Tutorials und viel Googlen nicht gelöst bekomme. Ein ähnliches Problem hab ich hier im Forum auch nicht gefunden.

Mein Test Script ist ganz einfach, eine Klasse die eine "Kiste Wasser" verwaltet. Man kann Flaschen rausnehmen, reinstellen, trinken und füllen, also alles ziemlich sinnlos :D . Dann hab ich das Script mit einer neuen Klasse erweitert welche die Wasser Kisten Klasse mit Buttons darstellen soll. Funktioniert alles wunderbar, nur eines nicht.
In ein per gtk.ScrollWindow() und gtk.TextView() erstelltes Text Fenster werden die änderungen eingetragen, und hier kommt das Problem:
Wenn das Text Fenster voll ist (d.h. wenn man nach unten scrollen muss), soll automatisch nach unten gescrollt werden.

Wie realisiere ich das?

Freue mich über jede Antwort :)

Code:

Code: Alles auswählen

import gtk
import pygtk

class kisteWasser:
	volle_flaschen = 12
	leere_flaschen = 0
	
	def flasche_rausnehmen(self, arg):
		if(self.volle_flaschen > 0):
			self.volle_flaschen -= 1
			self.show_message("Eine volle Flasche wurde rausgenommen!\n")
		elif(self.leere_flaschen > 0):
			self.leere_flaschen -= 1
			self.show_message("Eine leere Flasche wurde rausgenommen!\n")
		else:
			self.show_message("Die Kiste ist leer!\n")
	
	def flasche_reinstellen(self, arg):
		if((self.volle_flaschen + self.leere_flaschen) < 12):
			self.volle_flaschen += 1
			self.show_message("Eine volle Flasche wurde reingestellt!\n")
		else:
			self.show_message("Die Kiste ist voll!\n")
	
	def flasche_trinken(self, arg):
		if(self.volle_flaschen > 0):
			self.volle_flaschen -= 1
			self.leere_flaschen += 1
			self.show_message("Eine Flasche wurde ausgetrunken!\n")
		else:
			self.show_message("In der Kiste sind keine vollen Flaschen mehr!\n")
	
	def flasche_fuellen(self, arg):
		if(self.leere_flaschen > 0):
			self.volle_flaschen += 1
			self.leere_flaschen -= 1
			
			self.show_message("Eine Falsche wurde gefuellt!\n")
		else:
			self.show_message("Die Kiste hat keine leeren Flaschen!\n")
			
	def status(self, arg):
			self.show_message("In der Kiste stehen %d volle und %d leere Flaschen\n" % (self.volle_flaschen, self.leere_flaschen))


class kisteWindow(kisteWasser):
	def __init__(self):
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		
		self.box = gtk.VBox(False, 0)
		
		self.but_rausnehmen = gtk.Button("Flasche rausnehmen!")
		self.but_reinstellen = gtk.Button("Flasche reinstellen!")
		self.but_trinken = gtk.Button("Flasche trinken!")
		self.but_fuellen = gtk.Button("Flasche fuellen!")
		self.but_status = gtk.Button("Status der Kiste!")
		self.but_quit = gtk.Button("Beenden!")
		
		self.lab_kiste = gtk.Label("Kisten Optionen")
		self.lab_quit = gtk.Label("\nBeenden")
		self.lab_space = gtk.Label("\n\n\n")
		
		self.sep1 = gtk.HSeparator()
		self.sep2 = gtk.HSeparator()
		
		self.lab_kiste.set_alignment(0, 0)
		self.lab_quit.set_alignment(0, 0)
		
		self.sc_win = gtk.ScrolledWindow()
		self.sc_win.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		
		self.text = gtk.TextView()
		self.text.set_wrap_mode(True)
		self.text.set_editable(False)
		
		self.sc_win.add(self.text)
		
		self.but_rausnehmen.connect("clicked", self.flasche_rausnehmen)
		self.but_reinstellen.connect("clicked", self.flasche_reinstellen)
		self.but_trinken.connect("clicked", self.flasche_trinken)
		self.but_fuellen.connect("clicked", self.flasche_fuellen)
		self.but_status.connect("clicked", self.status)
		self.but_quit.connect("clicked", self.quit)
		
		self.window.connect("destroy", self.destroy)
		self.window.connect("delete_event", self.delete_event)
		
		self.box.pack_start(self.lab_kiste, False, False, 0)
		self.box.pack_start(self.sep1, False, True, 5)
		self.box.pack_start(self.but_rausnehmen, False, False, 0)
		self.box.pack_start(self.but_reinstellen, False, False, 0)
		self.box.pack_start(self.but_trinken, False, False, 0)
		self.box.pack_start(self.but_fuellen, False, False, 0)
		self.box.pack_start(self.but_status, False, False, 0)
		self.box.pack_start(self.lab_quit, False, False, 0)
		self.box.pack_start(self.sep2, False, True, 5)
		self.box.pack_start(self.but_quit, False, False, 0)
		self.box.pack_start(self.lab_space, False, False, 0)
		self.box.pack_start(self.sc_win, False, False, 0)
		
		self.lab_kiste.show()
		self.sep1.show()
		self.but_rausnehmen.show()
		self.but_reinstellen.show()
		self.but_trinken.show()
		self.but_fuellen.show()
		self.but_status.show()
		self.lab_quit.show()
		self.sep2.show()
		self.but_quit.show()
		self.lab_space.show()
		self.text.show()
		self.sc_win.show()
		
		self.window.set_border_width(60)
		self.window.set_title("Eine Kiste mit Wasser")
		self.window.set_default_size(640, 400)
		
		self.window.add(self.box)
		
		self.box.show()
		self.window.show()
		
		self.show_message("Eine Kiste mit 12 vollen Flaschen wurde erstellt!\n")
		
		gtk.main()
		
	def quit(self, arg):
		gtk.main_quit()
		
	def destroy(self, widget, data=None):
		gtk.main_quit()
		
	def delete_event(self, widget, data=None):
		print "cya..."
		
	def show_message(self, message):
		start, end = self.text.get_buffer().get_bounds()
		self.text.get_buffer().insert(end, message)
		
kisteWindow()
Benutzeravatar
br3z3l
User
Beiträge: 10
Registriert: Mittwoch 30. Januar 2008, 21:31
Kontaktdaten:

Also wenn ich es richtig verstanden habe möchtest du immer dass das ScrolledWindow den unteren Rand zeigt?

Dafür wäre dann gtk.ScrolledWindow.set_placement vermutlich ideal:
pygtk doc: Scrolled Window
Benutzeravatar
Cyber Mage
User
Beiträge: 5
Registriert: Samstag 2. Februar 2008, 10:48
Wohnort: Bremen
Kontaktdaten:

Hab ausprobiert, scrollt leider nicht automatisch runter :? . So wie ich das rauslese plaziert diese Funktion auch die Scrollbar und nicht das Fenster.
Benutzeravatar
br3z3l
User
Beiträge: 10
Registriert: Mittwoch 30. Januar 2008, 21:31
Kontaktdaten:

hm ... bin grad auf das hier noch gestoßen:
gtk.TextView.scroll_to_iter
und
gtk.TextView.scroll_to_mark

Link: http://www.pygtk.org/docs/pygtk/class-gtktextview.html
P.S.: Habe leider noch keine Zeit gefunden mich selbst damit zu spielen, werd morgen sehen ob ich paar Minuten erübrigen kann ;)
Benutzeravatar
Cyber Mage
User
Beiträge: 5
Registriert: Samstag 2. Februar 2008, 10:48
Wohnort: Bremen
Kontaktdaten:

Danke br3z3l, aber ich bekomm es leider nicht hin. Wenn du es hinbekommen hast, kannst du bitte Code posten?
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Code: Alles auswählen

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
import sys

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

def scrolled(widget, shadow=gtk.SHADOW_NONE):
    window = gtk.ScrolledWindow()
    window.set_shadow_type(shadow)
    window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    window.add(widget)
    return window

class MainWindow(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self,gtk.WINDOW_TOPLEVEL)
        self.set_default_size(220, 340)
        self.set_border_width(5)
        self.view = gtk.TextView()
        self.add(scrolled(self.view))
        self.connect("destroy", gtk.main_quit)

if __name__ == "__main__":
    MainWindow().show_all()
    gtk.main()
So geht das :)

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
Cyber Mage
User
Beiträge: 5
Registriert: Samstag 2. Februar 2008, 10:48
Wohnort: Bremen
Kontaktdaten:

Ich sehe da (bis auf den Schatten) nichts was ich nicht auch in meinem Code habe.

Vielleicht hast du die Frage falsch verstanden:
Ich will das beim automatischen einfügen (per klick auf einem Button) runtergescrollt wird.
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Cyber Mage hat geschrieben:Ich sehe da (bis auf den Schatten) nichts was ich nicht auch in meinem Code habe.

Vielleicht hast du die Frage falsch verstanden:
Ich will das beim automatischen einfügen (per klick auf einem Button) runtergescrollt wird.

Code: Alles auswählen

#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
import sys

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

def scrolled(widget, shadow=gtk.SHADOW_NONE):
    window = gtk.ScrolledWindow()
    window.set_shadow_type(shadow)
    window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    window.add(widget)
    return window

class MainWindow(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self,gtk.WINDOW_TOPLEVEL)
        self.set_default_size(20, 200)
        vbox = gtk.VBox()
        self.view = gtk.TextView()
        self.scrolled = scrolled(self.view)
        vbox.pack_start(self.scrolled)
        button = gtk.Button("Add Bottle")
        button.connect("clicked", self.add_bottle)
        vbox.pack_end(button, False, False)
        self.add(vbox)
        self.connect("destroy", gtk.main_quit)

    def add_bottle(self, sender):
        buff = self.view.get_buffer()
        buff.insert(buff.get_end_iter(), "foo\n")
        adj = self.scrolled.get_vadjustment()
        adj.set_value(adj.props.upper)
#        self.view.scroll_to_iter(buff.get_end_iter(), 0.0, True, 0.0, 0.0)

if __name__ == "__main__":
    MainWindow().show_all()
    gtk.main()
Das wollte ich eigentlich pasten. :)
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Benutzeravatar
Cyber Mage
User
Beiträge: 5
Registriert: Samstag 2. Februar 2008, 10:48
Wohnort: Bremen
Kontaktdaten:

Danke veers, genauso wollte ich es haben =)
Antworten