Rafraîchir un cadre tkinter en appuyant sur le bouton

j'utilise le code de Switch entre deux cadres dans tkinter pour faire mon GUI. J'ai un cadre avec des boutons Rafraîchir et redémarrer.

mon idée originale était que le bouton de redémarrage aille à la page de départ comme dans le code ci-dessous mais si ce cadre est appelé à nouveau il a les entrées de la tentative précédente montrant toujours.

j'ai essayé.destroy() pour le bouton refresh mais j'ai un message traceback quand j'appelle encore le cadre PLG.

pour le bouton Redémarrer, comment fermer le cadre PLG, aller à la page de démarrage et ensuite pouvoir sélectionner à nouveau PLG?

pour le bouton Rafraîchir, Comment puis-je supprimer les entrées dans l'entrée widget et texte arrear afin qu'une autre entrée puisse être faite et nouvelle réponse retournée?

class PLG(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Enter the engine size (cc) below", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)
        vcmd = (self.register(self.onValidate), '%S')
        self.weight_entry = tk.Entry(self, validate='key', vcmd = vcmd)
        self.weight_entry.pack(pady = 10)
        tk.Button(self, text='Click here to display price', command=self.show_option).pack()
        self.text = tk.Text(self)
        self.text.pack(pady = 10)
        self.text.config(state='disabled')
        restart_button = tk.Button(self, text="Restart",
              command=self.restart)
        restart_button.pack()
        refresh_button = tk.Button(self, text="Refresh", command=self.refresh).pack() 
        refresh_button.pack()  

    def onValidate(self,S):
    if S in ['0','1','2', '3', '4', '5', '6', '7', '8', '9']: 
        return True
    else:
        self.bell() # adds a sound effect to error
        self.text.delete(1.0, tk.END) # deletes the error message if valid entry provided
        self.text.insert(tk.END, "Invalid entry.  Please try again.") # displays an error message if a number not provided in entry widget
        return False

    def restart(self):
        self.refresh()
        show_frame("StartPage")

    def refresh(self):
        self.text.config(state='normal')
        self.weight_entry.delete(0,tk.END)
        self.text.delete("1.0", "end")

des conseils sur ces deux éléments seraient appréciés.

0
demandé sur bagpuss 2017-07-12 21:04:20

2 réponses

la première étape est d'avoir votre bouton appeler une fonction appropriée plutôt que d'utiliser lambda . À moins que vous ne compreniez pourquoi et quand utiliser lambda , cela rend généralement le code plus difficile à écrire et à comprendre.

une Fois que vous avez appeler une fonction, vous pouvez utiliser la fonction pour effacer les entrées.

exemple:

class PLG(tk.Frame):
    def __init__(self, parent, controller):
        ...
        tk.Button(self, text="Restart", command=self.restart)
        tk.Button(self, text="Refresh", command=self.refresh)
        ...

    def restart(self):
        self.refresh()
        self.controller.show_frame("StartPage")

    def refresh(self):
        self.weight_entry.delete(0, "end")
        self.text.delete("1.0", "end")
0
répondu Bryan Oakley 2017-07-13 14:52:35

la question de L'OP portait sur la suppression des champs d'entrée de sorte que l'entrée préalable n'est pas encore dans la page lorsque vous vous attendiez à voir des champs vides pour une nouvelle entrée. Je poste le code fini tout en omettant les caractéristiques du code original de L'OP qui n'étaient pas pertinentes à sa question afin que la solution puisse facilement être vue dans son contexte complet. J'avais cherché à résoudre ce problème avec ce même code de changement de cadre des célèbres tutoriels de Bryan Oakley sur ce sujet. J'ai aussi inclus une version alternative en utilisant grid_remove au lieu de tkraise puisque c'est ainsi que j'ai résolu le problème des cadres toujours actifs mais invisibles essayant de participer au focus transversal alors que l'utilisateur essaie de tabuler à travers la page. Il a également gardé les cadres de tous les essayer d'être de la même taille.

import tkinter as tk

class SampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        # alternate ways to create the frames & append to frames dict: comment out one or the other

        for F in (StartPage, PLG):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        # self.frames["StartPage"] = StartPage(parent=container, controller=self) 
        # self.frames["PLG"] = PLG(parent=container, controller=self)
        # self.frames["StartPage"].grid(row=0, column=0, sticky="nsew")
        # self.frames["PLG"].grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

    # alternate version of show_frame: comment out one or the other

    def show_frame(self, page_name):
        for frame in self.frames.values():
            frame.grid_remove()
        frame = self.frames[page_name]
        frame.grid()

    # def show_frame(self, page_name):
        # frame = self.frames[page_name]
        # frame.tkraise()

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller

        label = tk.Label(self, text="start page")
        label.pack(side="top", fill="x", pady=10)

        button1 = tk.Button(self, text="Go to Page One", command=lambda: controller.show_frame("PLG"))
        button1.pack()        

        button2 = tk.Button(self, text="focus traversal demo only")
        button2.pack()
        button2.focus_set()

        button3 = tk.Button(self, text="another dummy button")
        button3.pack()

        lbl = tk.Label(self, text="tkraise messes up focus traversal\nwhich you can see by testing the two versions of show_frame.()\nUsing grid_remove instead of tkraise solves that,\nwhile preventing frames from being unable to resize to fit their own contents.")
        lbl.pack()

class PLG(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Enter something below; the two buttons clear what you type.")
        label.pack(side="top", fill="x", pady=10)
        self.wentry = tk.Entry(self)
        self.wentry.pack(pady = 10)
        self.text = tk.Text(self)
        self.text.pack(pady = 10)
        restart_button = tk.Button(self, text="Restart", command=self.restart)
        restart_button.pack()
        refresh_button = tk.Button(self, text="Refresh", command=self.refresh) 
        refresh_button.pack()  

    def restart(self):
        self.refresh()
        self.controller.show_frame("StartPage")

    def refresh(self):
        self.wentry.delete(0, "end")
        self.text.delete("1.0", "end")
        # set focus to any widget except a Text widget so focus doesn't get stuck in a Text widget when page hides
        self.wentry.focus_set()

if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
0
répondu Lutherman 2018-08-28 02:31:22