2017-09-06 7 views
0

De la réponse donnée par Bryan Oakley à la question «Basculer entre deux images en tkinter», je vais changer le fonctionnement du bouton en page deux.Basculer entre les images dans tkinter en utilisant les fonctions

Sur la page un, avec command=lambda: controller.show_frame(“StartPage”), ça marche comme il se doit.

Sur la page deux, je veux ajouter quelque chose, puis revenir en arrière, mais cela ne fonctionne pas.

Pourquoi mon rappel n'est-il pas appelé?

import tkinter as tk    # python 3 
from tkinter import font as tkfont # python 3 

class SampleApp(tk.Tk): 

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

     self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic") 

     # the container is where we'll stack a bunch of frames 
     # on top of each other, then the one we want visible 
     # will be raised above the others 
     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 = {} 
     for F in (StartPage, PageOne, PageTwo): 
      page_name = F.__name__ 
      frame = F(parent=container, controller=self) 
      self.frames[page_name] = frame 

      # put all of the pages in the same location; 
      # the one on the top of the stacking order 
      # will be the one that is visible. 
      frame.grid(row=0, column=0, sticky="nsew") 

     self.show_frame("StartPage") 

    def show_frame(self, page_name): 
     '''Show a frame for the given 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="This is the start page", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 

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


class PageOne(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     label = tk.Label(self, text="This is page 1", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 
     button = tk.Button(self, text="Go to the start page", 
          command=lambda: controller.show_frame("StartPage")) 
     button.pack() 


class PageTwo(tk.Frame): 

    def __init__(self, parent, controller): 
     tk.Frame.__init__(self, parent) 
     self.controller = controller 
     label = tk.Label(self, text="This is page 2", font=controller.title_font) 
     label.pack(side="top", fill="x", pady=10) 
     button = tk.Button(self, text="Go to the start page", 
          command=self.go_to()) 
     button.pack() 
    def go_to(self): 
     # Add something to do    
     self.controller.show_frame("StartPage") 


if __name__ == "__main__": 
    app = SampleApp() 
    app.mainloop() 

Répondre

0

Le problème est que l'argument de mot-clé command de Button prend une fonction. Vous créez votre bouton avec tk.Button(self, ..., command=self.go_to()), la commande est donc self.go_to(), ce qui correspond à None.

Pourquoi est-ce le cas? go_to est défini comme suit:

def go_to(self): 
    # Add something to do 
    self.controller.show_frame("StartPage") 

Quand Python vient à travers command=self.go_to(), il appelle go_to, et passe la valeur retournée à l'option command. Cette valeur est None (impliquée par l'absence d'une instruction return), votre commande est donc None et votre bouton n'a aucun effet.

Vous devez supprimer les parenthèses, de manière à avoir tk.Button(self, ..., command=self.go_to).

+0

Merci. C'était devant mes yeux et je ne pouvais pas le voir. Merci – ogeretal

+0

Juste une question de moe, si go_to utilise un paramètre pour faire quelque chose et ensuite il retourne à StartPage, comment l'implémentez-vous (parce que maintenant les parenthèses sont nécessaires)? – ogeretal

+0

@ogeretal Soit l'entourer d'une fonction sans argument, soit utiliser un lambda, tel que 'command = lambda: self.go_to (x, y)'. Ce lambda signifie "cette fonction qui ne prend aucun argument et qui appelle f avec x et y", donc c'est une fonction comme prévu. –