GTK/Glade Entry - - - Anfängerproblem

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
webber
User
Beiträge: 6
Registriert: Freitag 11. Januar 2019, 13:29

Hallo liebe Profis,

nachdem ich mich etwas in Python eingearbeitet habe, mache ich mich an GTK/GLADE zu schaffen ... und stoße gleich auf ein Problem mit einem Eingabefeld (Entry) das ich nicht auslesen kann.

Aussehen: Kleines Fenster mit einem Button und einem Eingabefeld.

Erstellung des Fensters nebst Widgets funktioniert prima. Auch den Klick auf den Button kann ich auswerten. Jedoch das Auslesen des Textfeldes (beim Klick auf den Button) bekomme ich nicht hin.

Einige meiner erbärmlichen Versuche stehen unter "def on_button1_clicked ..." und sind auskommentiert.

Was mache ich falsch? Was muss ich ergänzen? Herzlichen Dank für Eure (anfägerverständliche) Hilfe.

Code: Alles auswählen

#****PYTHON Code****
#!/usr/bin/python
# -*- coding: utf-8 -*-
import gi
gi.require_version("Gtk", "3.0")

from gi.repository import Gtk

class Handler:
    def on_window_destroy(self, *args):
        Gtk.main_quit()
    
    def on_button1_clicked(self, *args):
        print("Button gedrückt")                                                   [b]#funktioniert[/b]
        #print (GtkEntry.textbox1.get_text())                       [b] #funktioniert nicht[/b]
        #print (builder.textbox1.get_text())                            [b]#funktioniert nicht[/b]
        #print(self.get_object('textbox1').get_text())         [b]#funktioniert auch nicht[/b]

class Example:
    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file("/home/pi/glade/2-4-1-a.glade")
        self.builder.connect_signals(Handler())
        window = self.builder.get_object("window")
        window.show_all()

    def main(self):
        Gtk.main()

x = Example()
x.main()



#**** GLADE/GTK-Code ****
?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkApplicationWindow" id="window">
    <property name="can_focus">False</property>
    <property name="title" translatable="yes">Titel</property>
    <property name="window_position">center-always</property>
    <property name="gravity">center</property>
    <signal name="destroy" handler="on_window_destroy" swapped="no"/>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkButton" id="button1">
            <property name="label" translatable="yes">button</property>
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="receives_default">True</property>
            <signal name="clicked" handler="on_button-1_clicked" swapped="no"/>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkEntry" id="textbox1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="text" translatable="yes">Hier Text eingeben</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
  </object>
</interface>
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst deinem Handler den Zustand, auf den er sich beziehen soll, schon mitteilen. Fuehr ein Konstruktor-Argument ein, in dem du zB den builder uebergibst, und dann im Konstruktor an self._builder bindest.

Dann kannst du in deinem Handler "self._builder.get_object" ausfuehern.

Durchnummerierte Namen von Controls und ganz generell sind uebrigens Mist.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@webber: es wäre gut, wenn Du auch die Fehlermeldung(en) posten würdest, die Du bekommst, da steht nämlich drin, warum das nicht funktioniert.
Programmieren ist auch nicht raten? Woher hast Du denn die verschiedenen Varianten? GtkEntry und builder sind beide nicht definiert, `builder` ist nur ein Attribut der Example-Instanz, und Handler hat keine Methode get_object. Die hat wiederum nur der builder von Example. Die Lösung ist also, dass Du dem Handler in __init__ die Example-Instanz übergibst, mit der Du dann get_object von builder aufrufst.
webber
User
Beiträge: 6
Registriert: Freitag 11. Januar 2019, 13:29

Sirius3 hat geschrieben: Freitag 11. Januar 2019, 14:27 @webber: es wäre gut, wenn Du auch die Fehlermeldung(en) posten würdest, die Du bekommst, da steht nämlich drin, warum das nicht funktioniert.
Programmieren ist auch nicht raten? Woher hast Du denn die verschiedenen Varianten? GtkEntry und builder sind beide nicht definiert, `builder` ist nur ein Attribut der Example-Instanz, und Handler hat keine Methode get_object. Die hat wiederum nur der builder von Example. Die Lösung ist also, dass Du dem Handler in __init__ die Example-Instanz übergibst, mit der Du dann get_object von builder aufrufst.
Moin Sirius,

Du hast Recht, ich rate mehr, als dass ich derzeit wirklich weiß, was ich tue. :oops:
(Ich brauche halt "Hallo Welt" in ganz kleinen Schritten :lol: )
Deinem Rat entsprechend habe ich die __init__ wie folgt modifiziert:

Code: Alles auswählen

    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file("/home/pi/glade/2-4-1-a.glade")
        self.builder.connect_signals(Handler())
        window = self.builder.get_object("window")
        textfeld = self.builder.get_object("textbox1")     # <--- NEU
        window.show_all()
Ich bekomme dadurch zumindest keine Fehlermeldung. Aber habe ich es auch richtig gemacht?

Und, wie wäre dann der ichtige Aufruf, denn folgendes funktioniert natürlich auch nicht, weil "textfeld" als nicht definiert gilt.

Code: Alles auswählen

   def on_button1_clicked(self, *args):
        print("Button gedrückt")         
        print(textfeld)
         
Danke für Dein Bemühen mich (schrittchenweise) schlauer zu machen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du mußt das Objekt `textfeld` an Handler.__init__ übergeben, damit Du es an ein Attribut binden kannst, damit es in Handler-Methoden verwendet werden kann.
Das sind Grundlagen der objektorientierten Programmierung. Ohne die wirklich gut zu können, macht GUI-Programmierung wenig Sinn.
webber
User
Beiträge: 6
Registriert: Freitag 11. Januar 2019, 13:29

Ja, da hast Du den Finger in die Wunde gelegt. Mit der OOP stehe ich komplett auf Kriegsfuß.
Dann werde ich meine Ambition auf ein kleines Userinterface für mein Programm wohl erst einmal begraben müssen. (Oder Python an PHP/HTML anbinden. Denn da habe ich derzeit mehr Chancen.) :x
Antworten