Werte werden nicht angezeigt

Fragen zu Tkinter.
Antworten
kitebuggy
User
Beiträge: 29
Registriert: Donnerstag 5. August 2021, 21:11

Hallo

Ich definiere ein Dictionnary:
diction={1:"A",2:"B",3:"C"}

Im Codeauschnitt kommt es zu Problemen:

Code: Alles auswählen

 key_list=list(diction.keys())
 val_list=list(diction.values())
 r=1
 for key in key_list:
            print("Key:",key)
            self.username=StringVar(value="diction.get(key)")
            print("Wert: ",diction.get(key))
            key_=ttk.Label(mainframe,text=key)
            key_.grid(column=1,row=r)
            #name=ttk.Label(mainframe,text=self.username.get())
            name=ttk.Entry(mainframe,textvariable=self.username)
            name.grid(column=2,row=r)
            #name.insert(0,diction.get(key))
            r+=1
 
Dieser Abschnitt soll die Schlüssel und deren entsprechende Werte anzeigen. Tut er aber nicht. Stattdessen wird nur der letze Wert angezeigt. Alle anderen Werte sind leer. Die SchLüssel werden korrekt angezeigt.
Ersetze ich nun den ttk.Entry durch ttk.Label funktioniert alles, jedoch will ich die Werte in einem Entry haben, da ich diese verändern möchte.
Komischerweise funktioniert auch die Schleife korrekt, wenn ich in Thonny den Debugger starte und dann durchlaufen lasse.
Die print-Anweisungen dienen nur zum Debuggen.

Mein System:
Linux debian 5.10.0-8-amd64 #1 SMP Debian 5.10.46-3 (2021-07-28) x86_64 GNU/Linux

Danke für jede Idee.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst schon pro Schlüssel eine Variable anlegen. Nicht nur eine für alle, die dann logischerweise auch nur einen benennen kann. Auch diese legt man in einem Wörterbuch ab.

Code: Alles auswählen

self._name_vars = {} 
for name, wert in diction:
     self._name_vars[name] = tk.StringVar(wert)
     ttk.Entry(mainframe, textvariable=self._name_vars[name])
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

self innerhalb einer Schleife zu belegen, ist immer ein Zeichen dafür, dass man irgendetwas falsch macht, weil ein Attribut ja auch nach dem Ende der Funktion weiter bestehen soll, es gleichzeitig aber immer innerhalb einer Schleife wieder überschrieben wird.

`val_list` wird definiert aber nicht benutzt. `key_list` ist eine Liste die unnötig ist. Variablennamen sollten keine Datentypen enthalten und aussagekräftig sein.
Wenn man eine Zählvariable zusätzlich zu den Elementen einer Liste braucht benutzt man enumerate.
Auch StringVar braucht einen `parent`. Der String "diction.get(key)" entspricht nicht dem, was Du wahrscheinlich willst. Wenn man sowohl Schlüssel als auch Wert möchte, benutzt man items.
Nicht alles muß man an einen Namen binden.
Ich konnte keine besseren Namen für key und value finden, weil ich nicht weiß, was in dem Wörterbuch gespeichert ist. Das solltest Du noch ändern:

Code: Alles auswählen

self.text_variables = {}
for row, (key, value) in enumerate(diction.items(), 1):
    text_variable = tk.StringVar(mainframe, value=value)
    self.text_variables[key] = text_variable
    ttk.Label(mainframe, text=key).grid(column=1, row=row)
    ttk.Entry(mainframe, textvariable=text_variable).grid(column=2, row=row)
kitebuggy
User
Beiträge: 29
Registriert: Donnerstag 5. August 2021, 21:11

Danke, jetzt klappt's. Wusste nichts von enumerate. Bin eben Anfänger.
Habe ein bischen damit gespielt und jetzt auch verstanden, wofür es steht.
Python ist schon toll. Man bekommt ein Buffet mit Befehlen zu allem möglichen (und unmöglichem :-)) und muss nur entsprechend auswählen, was man tun will.
Ich denke zuviel in C/C++.

Danke
Antworten