GtkBuilder

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
whaeva
User
Beiträge: 66
Registriert: Mittwoch 25. Februar 2009, 15:30

Bin gerade dabei eine GUI zu bauen, und zwar anhand von der Reihe von
http://www.micahcarrick.com/12-24-2007/ ... art-1.html

Nun wird dort nicht libglade benutzt, sondern gtk-builder:
http://www.micahcarrick.com/05-30-2008/ ... e-faq.html

Ich bin auf der Suche nach einem ganz einfachen Beispiel nicht fündig geworden, wie ich ein Widget suchen kann.

Meinetwegen ein label widget dem ich in einen neuen Text zuweisen möchte, a la:

lbl = self.wTree.get_widget(”label1″)
lbl.set_text(”Hello World!”)
whaeva
User
Beiträge: 66
Registriert: Mittwoch 25. Februar 2009, 15:30

Habe doch noch etwas gefunden:
http://www.minipop.org/index.php/tutori ... thon-glade

Ist es allerdings wirklich notwendig, für jedes widget auch noch ein zusätzliches Objekt zu erzeugen?

Code: Alles auswählen

def __init__(self):
  builder = gtk.Builder()
  builder.add_from_file("hello.glade") 
  self.window = builder.get_object("window1")
  self.label1 = builder.get_object("label1")
  builder.connect_signals(self)
Das scheint mir sehr aufwändig !?

Schöner wär's, wenn in der Handlerfunktion einfach etwas wie

Code: Alles auswählen

self.get_object("label").set_markup("<span font="36">buh!</span>")
funktionieren würde
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Die Dokumentation sagt:
def get_object(name)
name :
Name of object to get.
Returns :
The object named name or None if it could not be found in the object tree.

Sofern es das Objekt gibt, müßte Deine Abkürzung eigentlich funktionieren. Was hast Du denn für eine Fehlermeldung?
whaeva
User
Beiträge: 66
Registriert: Mittwoch 25. Februar 2009, 15:30

Das Problem ist, dass wohl das builder-Objekt in der Handler-Funktion nicht mehr bekannt ist.
Vielleicht geht es dann mit self.builder....
Bei einer handvoll Widgets spricht ja nichts dagegen, das in der __init__ einem Objekt zuzuweisen - aber in großen Anwendungen wird es bestimmt irgendwie anders gemacht..
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ok ,das mit der Handler-Funktion hatte ich überlesen. Solange die eine Methode ;) Deiner Klasse ist, in der Du den builder initialisierst, geht das mit dem self.builder.

Generell ist es einfach sauberer, die Objekte über einen Bezeichner anzusprechen. Auch gewinnst Du hierdurch Flexibilität, falls sich z.B. in Deiner Gui was ändert.
Ich würds pragmatisch halten, willst nur eben mal an ObjektXY was ändern reicht sicher die get-Variante, mußt Du aber viele Zugriffe auf das Objekt tätigen, würd ich es dauerhaft im Konstruktor reinholen.
Peets
User
Beiträge: 4
Registriert: Mittwoch 29. Juli 2009, 08:22

... habe gerade beim python lernen das gleiche problem - vielleicht verstehe ich auch nicht genug von Objekt Orientierung oder python. pl06.glade mit glade 3 unter ubuntu linux erstellt, Hauptfenster ist sichtbar gemacht und neben dem Button noch ein entity Feld installiert. Funktioniert auch einwandfrei aber ich kann nicht auf die Entitiy zugreifen. Hab auch im Netz nix gefunden das ich verstehe.
Wie sieht die Lösung nun aus? Nach einem bekannten und guten Tutorial ( http://www.learningpython.com/2006/05/0 ... and-glade/ ) habe ich folgenden code laufen:

Code: Alles auswählen

class pl:
    """Python / GTK Test pl06"""
    def __init__(self):
        #Set the Glade file
        self.gladefile = "pl06.glade"  
        self.wTree = gtk.glade.XML(self.gladefile) 
        #Create our dictionay and connect it
        dic = { "on_button1_clicked" : self.btn1_clicked,
                "on_window1_destroy" : gtk.main_quit }
	self.wTree.signal_autoconnect(dic)

    def btn1_clicked(self, widget):
        e1 = self.wTree.get_widget("entry1")
        print "e1= ", e1
        help(e1)
        ...
zusätzlich zu dem Text und dem Button des bekannten Beispiels in __init__() habe ich die Funktion btn1_clicked() eingefügt die in das Textfeld von 'entry1' was schreiben soll (... weil ab da kein Versuch funktioniert)
help(e1) liefert:
  • Help on Entry in module gtk object:

    class Entry(Widget, Editable, CellEditable)
    | Object GtkEntry
    |
    | Signals from GtkEntry:
    | activate ()
    | move-cursor (GtkMovementStep, gint, gboolean)
    . . .
    | icon-press (GtkEntryIconPosition, GdkEvent)
    | icon-release (GtkEntryIconPosition, GdkEvent)
    |
    | Properties from GtkEntry:
    | cursor-position -> gint: Zeigerposition
    | Die momentane Position des Einfügezeigers, in Zeichen
    | selection-bound -> gint: Markierungsgrenze
    | Der Abstand des gegenüberliegenden Endes der Markierung vom Zeiger in Zeichen
    | editable -> gboolean: Bearbeitbar
    | Sollen die Feldinhalte bearbeitet werden können?
    . . .
    | text -> gchararray: Text
    | Der Inhalt des Feldes
    . . .
Alle Versuche, mit 'e1.irgendwas' Werte zuzuweisen oder anzuzeigen scheitern, z. B.

Code: Alles auswählen

    def btn1_clicked(self, widget):
        e1 = self.wTree.get_widget("entry1")
        print "e1= ", e1
        #help(e1)
        print "text ist: ", e1.text
führen zu Fehlermeldungen wie:

Code: Alles auswählen

e1=  <gtk.Entry object at 0xb6f46b94 (GtkEntry at 0x8ccd000)>
text ist: 
Traceback (most recent call last):
  File "pl06.py", line 33, in btn1_clicked
    print "text ist: ", e1.text
AttributeError: 'gtk.Entry' object has no attribute 'text'
Nun vermute ich als Anfänger, dass ich da syntaktisch was falsch habe oder dass ich die Strukturen in python noch nicht so gut verstehe. Wer kann da weiterhelfen?
--- der lange Beitrag tut mir leid - konnte aber aus meiner Sicht nicht viel kürzen 8---(
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Das sind Gtk-Properties, keine Python-Properties, die haben in Python dann immer entsprechende `get_##()/set_##()`-Methoden (also in dem Fall ``e1.get_text()``.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Peets
User
Beiträge: 4
Registriert: Mittwoch 29. Juli 2009, 08:22

... vielen Dank für den Hinweis! Das Programm sieht nun so aus und funktioniert:

Code: Alles auswählen

    def btn1_clicked(self, widget):
        e1 = self.wTree.get_widget("entry1")
        print "e1= ", e1
        print "text ist: ", e1.get_text()
        e1.set_text("hallo entry")
        print "und jetzt:", e1.get_text()
eine weitere Frage: wo kann man das am einfachsten nachlesen?
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Die Dokumentation von PyGTK würde sich anbieten.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Antworten