tkinter checkboxes

Fragen zu Tkinter.
Antworten
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Hey Leute ich verstehe nicht ganz warum meine Checkboxen nicht funktionieren kann mir jemand sagen wo mein Fehler liegt ?

Code: Alles auswählen

def edit_contact_gui(self):
        """GUI to edit the created contacts."""
        self.edit_contact_wd = tk.Tk()
        self.edit_contact_wd.title('Edit Contacts of the Phonebook:"%s"'\
                                   % self.book)
        self.button_edit = tk.Button(self.edit_contact_wd, text = 'Edit',\
                                     command = self.edit_contact)
        
        
        try:
            with open('%s.txt' % self.book, 'rb') as file:
                book = pickle.load(file)
                x = 1
                self.var_lst = []
                for i in book:
                    var = tk.IntVar()
                    tk.Label(self.edit_contact_wd, text = i).grid(row = x, \
                                                                    column = 0)
                    tk.Checkbutton(self.edit_contact_wd, text = 'edit', variable = var).grid\
                                                         (row = x, column = 1)
                    self.var_lst.append(var.get())
                    x += 1
                
                self.button_edit.grid(row = x+1, column = 1)
                
        except FileNotFoundError:
            tk.Label(self.edit_contact_wd, text = 'The phonebook has no \
entrys!', fg = 'red').grid(row = 1, column = 0)

    def edit_contact(self):
        print(self.var_lst)

        self.edit_contact_wd.mainloop()
Meine Ausgabe, als GUI funktioniert. Jedoch muss mir das Programm meiner Meinung nach in der Shell später durch die Funktion eine Liste mit 0 und 1 ausgeben. 0 dafür wo kein Hacken ist und 1 wo ich ein Hacken habe. Dies macht es jedoch nicht es gibt mir immer Listen aus mit 0 . Warum macht der Code das, wo liegt mein Fehler.

PS: habe natürlich
import pickle und import tkinter as tk, am Anfang meines Programmes.

Danke schonmal im vorraus.
BlackJack

@Fl4mer: Du steckst lauter 0en in die Liste. Die ändern sich später nicht auf magische Weise. Du musst die `IntVar`-Objekte in die Liste stecken und die zu dem Zeitpunkt nach ihrem aktuellen Wert fragen zu dem Du den aktuellen Wert auch wissen willst.
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Kannst du das mit vielleicht genauer erklären oder näher beschreiben finde meinen Fehler nicht. Sorry :( :K
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Fl4mer: "var.get()" liefert den **Wert** des IntVar, und der ist nunmal zum Zeitpunkt, an dem Du die Liste "var_lst" füllst, 0. Du willst die IntVar-Instanzen in der Liste speichern und bei Bedarf deren Wert dann auswerten, wenn Du die Werte haben willst.

Im Übrigen: Pickle ist kein Format, für die dauerhafte Speicherung von Daten. Nimm JSON oder CSV. Eine Tk-Instanz innerhalb einer Methode zu erzeugen, ist ungewöhnlich. Existiert wirklich nur diese eine Instanz?
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Aber ich verstehe nicht wie ich das in meinem Programm-Code ändern kann.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@Fl4mer: Was verstehst Du konkret an dem Satz "Du willst die IntVar-Instanzen in der Liste speichern und bei Bedarf deren Wert dann auswerten, wenn Du die Werte haben willst." nicht?
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Ich verstehe den Satz ich weiß aber nicht, wie ich die IntVar-Instanzen in der Liste speichere, bevor sie 0 zugeordnet bekommen haben.
BlackJack

@Fl4mer: Denen wird nirgends 0 zugeordnet, das ist der Standardwert nachdem sie erstellt wurden. Und man fügt die wie jedes andere Objekt von jedem beliebigen anderen Typ zu Listen hinzu: in dem man so ein Objekt beim `append()`-Aufruf als Argument übergibt. Du musst da halt nicht die 0en speichern die Du von den `IntVar`-Objeken abfragst, sondern nicht die Zahl abfragen sondern das `IntVar`-Objekt selbst an die Liste anhängen.

Und bei `edit_contact()` dann nicht einfach nur die Liste ausgeben, sondern *dort* dann durch die Liste mit den `IntVar`-Objekten gehen und den aktuellen Wert von jedem abfragen.

Edit:

Code: Alles auswählen

In [6]: var = tk.IntVar()

In [7]: var.get()
Out[7]: 0

In [8]: items = list()

In [9]: items.append(var.get())

In [10]: items
Out[10]: [0]

In [11]: var.set(42)

In [12]: items
Out[12]: [0]

In [13]: items = list()

In [14]: items.append(var)

In [15]: items
Out[15]: [<Tkinter.IntVar instance at 0x7ff3304e4950>]

In [16]: items[0].get()
Out[16]: 42

In [17]: var.set(23)

In [18]: items[0].get()
Out[18]: 23
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Meint ihr ich dass ich bei self.var_lst.append(var.get()) nur self.var_lst.append(var) hinschreibe und dann in der zweiten Funktion die var abrufe mit get() ? Wenn ja, dann löst dies aber nicht mein Problem, weil trotzdem nur 0 enthalten , wenn ich checkbuttons ankreuze.
BlackJack

@Fl4mer: Das kann bei dem gezeigten Code nicht sein. Sirius3 hatte es ja schon angedeutet: Es darf nur *ein* Exemplar von `Tk` geben. Das ist *das* Hauptfenster. Kann es sein das Du irgendwo anders vorher schon ein `Tk`-Objekt erzeugt hast? Zusätzliche Fenster macht man mit `Toplevel`.
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Ja ich habe eine ganze Klasse mit bis zu 4 Tk(). Daran liegt mein Fehler. Habe die vorherige Sache die ihr mir probiert habt zu erklären ämlich schon tausendmal ausprobiert und es hat nichts gändert.

Muss ich um mit toplevel zu arbeiten einfach nur tk.toplevel() angeben ?
Fl4mer
User
Beiträge: 25
Registriert: Donnerstag 24. November 2016, 19:10

Ok vorherige Frage hat sich erledigt. Habe es rausgefunden. Danke nochmal für die Unterstützung und das ich euch so verrückt gemacht habe.
Wusste nicht das es zu Fehlern kommt wenn ich zweimal tk verwende.
Antworten