Tkinter Button (doppelter command)

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
yildirim2665
User
Beiträge: 14
Registriert: Freitag 27. Januar 2023, 10:43

hallo zusammen,

habe folgendes Problem;
meine Funktion erstellt lokal ein Toplevel-Fenster, welches ich auch lokal mit command=Toplevel.destroy schließen kann, es soll aber auch eine Funktion aufrufen....??

Im Netz fand ich nur command=lamda:[func1,func2], da aber mein Fenster lokal erzeugt wurde, kann ich kein close-Funktion zum schließen benutzen,
was kann ich tun??
yildirim2665
User
Beiträge: 14
Registriert: Freitag 27. Januar 2023, 10:43

habe folgendes gemacht;

Code: Alles auswählen

 def insert(self):
                root2 = Toplevel()
                .........
                einfügen_Button = ttk.Label(root2,text='Einfügen',command=lambda[self.add_human, root2.destroy])

Beide Commands werden nicht ausgeführt!???
yildirim2665
User
Beiträge: 14
Registriert: Freitag 27. Januar 2023, 10:43

jetzt klappt es...Doppelpunkt und Klammern vergessen;

Code: Alles auswählen

 def insert(self):
                root2 = Toplevel()
                .........
                einfügen_Button = ttk.Label(root2,text='Einfügen',command=lambda:[self.add_human(), root2.destroy()])
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Uh. Das macht man eher nicht. Es ist ein zu verquaster Trick. Ein Weg, mehrere Statements auszufuehren waere zB eine lokale Funktion. Es gibt Leute, die finden die doof, aber ich benutze sie gerne fuer sowas. Der Vorteil: ein verstaendlich waehlbarer Name, keine unnoetige Liste erzeugt, dokumentierbar.
yildirim2665
User
Beiträge: 14
Registriert: Freitag 27. Januar 2023, 10:43

@_deets_ hey das was du sagst klappt nicht, da das Toplevelfenster lokal erzeugt wird, habe daher kein Zugriff auf das Toplevel-Fenster, wie ist denn eine üblichere Methode??

Code: Alles auswählen


    def del_human_root(self):
        
        if self.listmodel ==[]:
            self.show_empty_list()
        else:
            root3=Toplevel()
            namelabel = ttk.Label(root3,text='Name')
            namelabel.grid(row=1,column=1)
            entername = ttk.Entry(root3,textvariable=self.deletvariable)
            entername.grid(row=1,column=2)
            buttondel = ttk.Button(root3,text='Löschen',command= self.del_human())
            buttondel.grid(row=2,column=1)
            buttonquit = ttk.Button(root3,text='Abbruch',command= lambda:[root3.destroy(),root3.quit(),self.deletvariable.set('')])
            buttonquit.grid(row=2,column=2)

    def del_human(self):
        root3.destroy() # kein Zugriff, root lokal!
        root3.quit()    #  -"-
        filterhuman =[human for human in  self.listmodel if human['name']==self.deletvariable.get()]
        
        if filterhuman !=[]:
        
            if self.controller:
               
                self.controller.del_human(self.deletvariable.get())
                self.deletvar.set('')
        else:
            tkinter.messagebox.showinfo('Falsche Eingabe', 'Person nicht in der Liste')
            self.deletvariable.set('')
Benutzeravatar
__blackjack__
User
Beiträge: 13080
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@yildirim2665: Üblich wäre einen Dialog zu verwenden. Der Code macht insgesamt einen recht komischen Eindruck wie das da alles verteilt ist. Zum Beispiel, dass es ein `self.deletvariable` gibt was in dem neuen Fenster benutzt wird, was aber eigentlich nicht zu dem Zustand von `self` gehören sollte wenn das eigentlich nur temporär für das Löschen eines Eintrags verwendet wird.

Bei dem "Löschen"-Button wird `del_human()` aufgerufen statt die Methode als `command` zu übergeben.

`root3` ist als Name falsch, weil es nur *eine* Wurzel gibt und das ist das Hauptfenster. Die 3 in dem Namen macht auch gar keinen Sinn.

`filterhuman` ist komisch. Warum wird da eine Liste erstellt, wenn eigentlich nur interessant ist ob der Name in der Liste vorkommt?

Das geprüft werden muss ob `self.controller` existiert ist auch komisch. Wenn das nicht existiert ist das Objekt nicht wirklich funktionsfähig, das *muss* also existieren, dann muss man da aber nichts prüfen.

Edit: Und aus Benutzersicht wäre es deutlich angenehmer wenn man einfach aus einer Liste wählen könnte, statt das man sich beim Namen vertippen kann.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
yildirim2665
User
Beiträge: 14
Registriert: Freitag 27. Januar 2023, 10:43

@ __blackjack__ : danke für die Infos habe den Code soweit geändert.

'filterhuman' filtert die Person die gelöscht werden soll, hatte dies

Code: Alles auswählen

myitems = list(filter(lambda x: x['name'] == name, items))
im Netz gefunden, das habe ich dann umgeschrieben. Wie soll ich sonst die Person filtern? Die Liste besteht aus Dictionarys.

'Benutzersicht' Kann im Hauptfenster die Liste anzeigen und ausblenden. Dort könnte ich die Person auswählen, dies ist eine Alternative, die auch ohne die Liste anzuzeigen funktioniert. (vielleicht unnötig, aber ich versuche halt vieles auszuprobieren)

Code: Alles auswählen

def del_human_dialog(self):
        
        if self.listmodel ==[]:
            self.show_empty_list()
        else:
            name = simpledialog.askstring('Person löschen', 'Wie lautet der Name der Person, die gelöscht werden soll?:')
            self.del_human(name)
            
    def del_human(self,name):
        
        filterhuman =[human for human in  self.listmodel if human['name']==name]
        
        if filterhuman !=[]:
         
            self.controller.del_human(name)
            
        else:
            tkinter.messagebox.showinfo('Falsche Eingabe', 'Person nicht in der Liste')
Antworten