2017-08-02 2 views
0

Teil meines Programms fordert den Benutzer auf einen Probennummer in ein Eingabefeld eingeben und dann auf eine Schaltfläche klicken die generiert die Anzahl der Eingabe-Widgets darunter (um Informationen zu jedem Sample einzugeben). Die Eingabe-Widgets erscheinen genau wie erwartet, untereinander für die eingegebene Anzahl von Samples. Ich kann jetzt nicht herausfinden, wie man die Variablen für jedes dieser neuen Eintritts-Widgets trennt. Ich hatte gehofft, dass jeder mir erlauben würde, einen anderen Wert einzugeben, und sie dann über .get() zurückzurufen. Das ist nicht der Fall, sie ändern sich alle zusammen zu dem, was ich in eins tippe. Unten ist der Abschnitt des Codes, den ich glaube, ist das Problem:Ich habe mehrere tkinter Eintrag Widgets usign eine while-Schleife, und ich habe Probleme, die getrennte Variablen für jeden

normval_f= IntVar() 
    x= samp.get() 
    f=1 
    while f<=x: 
     f_entry = ttk.Entry(mainframe, width=7, textvariable=normval_f) 
     f_entry.grid(column=1, row=f+12) 
     f_label = ttk.Label(mainframe, text="Sample "+str(f)+ " value").grid(column=2, row=f+12, sticky=W) 
     f=f+1   

Antwort

0

Listen und Wörterbücher können sehr nützlich sein, wenn es um große Mengen oder sehr viele Widgets geht.

Unten ist ein Stück Code zu erreichen, was Sie in Ihrer Frage beschrieben.

Ich verwende eine Liste namens self.my_entries, um alle Einträge zu speichern, die basierend auf dem Wert dessen erstellt werden, was der Benutzer eingibt. Ich fügte auch eine kleine Fehlerbehandlung hinzu, falls der Benutzer versucht, etwas anderes als a einzugeben Wenn die Taste gedrückt wird, wird Nummer oder Nichts eingegeben.

Der erste Eintrag und Taste auf dem Root-Fenster platziert und für alle Eingabefelder, die wir einen Rahmen unter der ersten Schaltfläche hinzufügen erstellt werden werden. Dadurch können wir die Eingabefelder ein wenig einfacher verwalten, wenn wir das Feld später zurücksetzen wollen.

from tkinter import * 


class Example(Frame): 


    def __init__(self): 
     Frame.__init__(self) 

     self.pack() 
     self.my_entries = [] 

     self.entry1 = Entry(self) 
     self.entry1.grid(row = 0, column = 0) 
     Button(self, text="Set Entry Fields", command=self.create_entry_fields).grid(row = 1, column = 0) 

     self.frame2 = Frame(self) 
     self.frame2.grid(row = 2, column = 0) 

    def create_entry_fields(self): 
     x = 0 
     try: 
      x = int(self.entry1.get()) 
      if x != 0: 
       for i in range(x): 
        self.my_entries.append(Entry(self.frame2)) 
        self.my_entries[i].grid(row=i, column=1) 
        f_label = Label(self.frame2, text="Label {}: ".format(i+1)) 
        f_label.grid(row=i, column=0) 
      Button(self.frame2, text="Print to console", command=self.print_all_entries).grid(row=x, column=0, sticky = "nsew") 
      Button(self.frame2, text="Reset", command=self.clear_frame2).grid(row=x, column=1, sticky = "nsew") 
     except: 
      print("Invalid entry. Only numbers are allowed.") 

    def print_all_entries(self): 
     for i in self.my_entries: 
      print(i.get()) 

    def clear_frame2(self): 
     self.my_entries = [] 
     self.frame2.destroy() 
     self.frame2 = Frame(self) 
     self.frame2.grid(row = 2, column = 0) 


if __name__ == '__main__': 
    root = Tk() 
    test_app = Example() 
    root.mainloop() 

Lassen Sie mich wissen, wenn Sie Fragen zu dem oben genannten Code haben.

+0

wow! Vielen Dank dafür. Mit ein paar Änderungen passt das fast perfekt in mein Schema. Ich kann dir nicht genug danken !! – Ian

+0

@Ian: Ich bin froh zu helfen. –

+0

Nur ein Gedanke, aber wenn es zu schwierig ist, ist es keine große Sache. Gibt es eine Möglichkeit, eine Bildlaufleiste hinzuzufügen, wenn die Anzahl der Eingabe-Widgets die Bildschirmgröße überschreitet? Ich kann nicht den Weg, um das für mehrere Widgets zu erreichen scheinen ... – Ian

0

Ein paar Vorschläge; Verwenden Sie keine while-Schleife, verwenden Sie stattdessen eine for-Schleife. Zweitens würde ich vorschlagen, jede Ihrer Variablen in einer Liste oder, wie ich es getan habe, in einer Liste zu speichern. Im Moment überschreiben Sie Ihre Variablen jedes Mal, wenn Sie die Schleife durchlaufen, so dass Sie jedes Mal eine neue erstellen und sie irgendwo speichern müssen.

Hier ist ein Beispiel für das Speichern einer Anzahl von Feldern in einem Wörterbuch.

from tkinter import * 

class App(Frame): 
    def __init__(self,master): 
     Frame.__init__(self, master) 
     fields = ['name','age','gender'] 
     self.field_variables = {} 
     for idx,field in enumerate(fields): 
      self.field_variables[field] = StringVar() 
      f_entry = Entry(self,textvariable=self.field_variables[field]) 
      f_entry.grid(column=2,row=idx) 
      f_label = Label(self,text=field) 
      f_label.grid(column=1,row=idx) 

     go_btn = Button(self,text="Go",command=self.get_all) 
     go_btn.grid() 

    def get_all(self): 
     print(self.field_variables) 

if __name__ == '__main__': 
    root = Tk() 
    app = App(root) 
    app.grid() 
+0

Sie fehlen 'root.mainloop()' und Ihre print-Anweisung aus den Werten der einzelnen Felder nicht gedruckt, aber die StringVar Objekt Standort statt. –