dynamisches Beschreiben tkinter-Label

Fragen zu Tkinter.
Antworten
joe2000
User
Beiträge: 7
Registriert: Montag 24. Oktober 2022, 15:35

Hallo zusammen,
ich bin gerade dabei mich in Python einzuarbeiten und beschäftige mich aktuell mit tkinter und Klassen. Hierzu habe ich mir folgende Aufgabe gestellt: In einer GUI soll in ein Eingabefeld ein Text eingegeben werden, welcher dann unmittelbar in einem Label angezeigt werden soll. Das dynamische Auslesen des Eingabefeldes funktioniert, ich habe es allerdings bisher nicht geschafft das Label korrekt anzusprechen: Über self.label.config(text=eingabe) funktioniert es nicht (Fehlermeldung: 'NoneType' objecthasnoattribute 'config'), und auch über andere Befehle habe ich es nicht hinbekommen. Ich komme an dieser Stelle nicht weiter und wäre wirklich sehr dankbar, wenn Ihr mir weiterhelfen könntet. Hier der Code:

Code: Alles auswählen

fromtkinterimportTk, ttk, Label, Entry, Frame
fromtkinterimportStringVar

classgui:

    def__init__(self, master):
        master.title("test")
        formular = Frame(master)
        formular.grid(row=0)

        self.var = StringVar() 
        self.entry = ttk.Entry(formular, textvariable =self.var)
        self.entry.grid(sticky="W", row=0, column=0)
        self.entry.bind("<KeyRelease>", self.entry_change)  

        self.label=Label(formular, text='Eingabe: ').grid(sticky="W", row=1)

    defentry_change(self, event):
        eingabe=self.entry.get()
        print(eingabe)
        self.label.config(text=eingabe)#AttributeError: 'NoneType' objecthasnoattribute 'config'

root = Tk() 
root.geometry("300x100")
my_gui = gui(root) 
root.mainloop()
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Rückgabe von Grid ist nicht das Widget, sondern None. Zerteil den Ausdruck in zwei, und dann geht das auch.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@joe2000: Klassennamen werden in Python per Konvention in PascalCase geschrieben, also `Gui` statt `gui`. Dann kommt man auch nicht in die Situation so sinnfreie Kürzel wie `my_` in Namen zu verwenden damit Exemplar und Klasse nicht gleich heissen. Das wäre dann einfach ``gui = Gui(root)``.

Das Beispiel nutzt `self.var` überhaupt nicht. *Das* würde aber ausreichen wenn man das auch für das `Label` verwenden würde. Dann braucht man gar keine Ereignisbehandlung damit beides das gleiche anzeigt.

`formular` klingt als wäre es aus einer anderen Programmiersprache. Hier würde es sich vielleicht auch anbieten, dass `Gui` von `Frame` erbt.

Den Fenstertitel würde man in der `__init__()` eher nicht ändern, denn das würde voraussetzen, dass man weiss das `master` nicht irgend ein Container-Widget ist, sondern ein Fenster sein muss.

Das Hauptprogramm sollte in einer Funktion stehen, damit keine globalen Variablen entstehen, die aus versehen mal in einer Funktion oder Methode benutzt werden könnten.

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from tkinter import ttk


class Gui(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        self.var = tk.StringVar()
        self.entry = ttk.Entry(self, textvariable=self.var)
        self.entry.grid(sticky=tk.W, row=0, column=0)
        self.label = tk.Label(self, textvariable=self.var)
        self.label.grid(sticky=tk.W, row=1, column=0)


def main():
    root = tk.Tk()
    root.title("test")
    gui = Gui(root)
    gui.pack()
    root.mainloop()


if __name__ == "__main__":
    main()
Ein loslassen einer Taste bedeutet übrigens nicht zwingend eine Veränderung des Inhalts. Da wäre es wahrscheinlich sinnvoller mit dem `StringVar`-Objekt und der `trace_add()`-Methode zu arbeiten.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
joe2000
User
Beiträge: 7
Registriert: Montag 24. Oktober 2022, 15:35

@deets: danke, so funktioniert es dann. Eigentlich logisch…
@blackjack: ebenfalls danke, für mich als Einsteiger sind gerade diese Hinweise sehr wichtig.
Antworten