2014-06-04 122 views
0

我遇到了一个问题,我试图制作一个简单的数学游戏,并且我有一些按钮会将用户从“说明”框架带回主菜单。问题是,当我点击按钮返回到“说明”框架时,画布对象将不会在第二次创建它们时显示。这里是我的代码:画布对象不会为Tkinter重新创建

from tkinter import * 

class GUI: 
    def __init__(self, parent): 

     self.parent = parent 

#============================================================================== 
#CREATE MENU FRAMES 
#============================================================================== 
     self.menu_frame = Frame(parent, width = 800, height = 600) 
     self.menu_frame.pack_propagate(0) 

     self.create_menu() 

#============================================================================== 
#CREATE HTP AND SETTINGS FRAME 
#============================================================================== 
     self.initial_frame = Frame(parent, width = 800, height = 600) 
     self.initial_frame.pack_propagate(0) 
#============================================================================== 
#CREATE HOW TO PLAY FRAME 
#============================================================================== 
     self.htp_frame = Frame(parent, width = 800, height = 600) 
     self.htp_frame.pack_propagate(0) 

#============================================================================== 
#CREATE SETTINGS FRAME 
#============================================================================== 
     self.settings_frame = Frame(parent, width = 800, height = 600) 
     self.settings_frame.pack_propagate(0) 


    def create_menu(self): 

     self.menu_frame.pack() 

     self.canvas = Canvas(self.menu_frame, width=800, height=600) 
     self.canvas.background = PhotoImage(file = "images/math_background.gif") 
     self.canvas.pack(expand = YES, fill = BOTH) 
     self.canvas.create_image(400, 300, image=self.canvas.background) 

     self.menu_text = Label(self.menu_frame, text = "Mathematics Program", font = ("Rockwell", "36", "bold"), fg = "black", pady = 30) 
     self.menu_text.pack() 

     self.start_button = Button(self.menu_frame, text = "Start", font = ("Arial", "18", "bold"), width = 30, bg = "Light Goldenrod Yellow") 
     self.start_button.pack() 
     self.canvas.create_window(400, 200, window=self.start_button) 
     self.instructions_button = Button(self.menu_frame, text = "How to Play", font = ("Arial", "18", "bold"), width = 30, bg = "Light Goldenrod Yellow", command = self.create_htp) 
     self.instructions_button.pack() 
     self.canvas.create_window(400, 300, window=self.instructions_button) 
     self.settings_button = Button(self.menu_frame, text = "Settings", font = ("Arial", "18", "bold"), width = 30, bg = "Light Goldenrod Yellow", command = self.create_settings) 
     self.settings_button.pack() 
     self.canvas.create_window(400, 400, window=self.settings_button) 
     self.quit_button = Button(self.menu_frame, text = "Quit", font = ("Arial", "18", "bold"), width = 30,bg = "Light Goldenrod Yellow", command = self.quit_program) 
     self.quit_button.pack() 
     self.canvas.create_window(400, 500, window=self.quit_button) 
     self.canvas.create_text(400, 100, text = "Mathematics Program", font = ("Rockwell", "36", "bold"), fill = "Light Goldenrod Yellow") 



    def create_bg(self): 
     self.menu_frame.pack_forget() 
     self.initial_frame.pack() 
     self.canvas2 = Canvas(self.initial_frame, width=800, height = 600) 
     self.canvas2.pack(expand = YES, fill = BOTH) 
     self.canvas2.initial_background = PhotoImage(file = "images/orange_bg.gif") 
     self.canvas2.create_image(400, 300, image=self.canvas2.initial_background) 

    def create_htp(self): 
     self.create_bg() 
     self.canvas2.create_text(400, 100, font = ("Arial", "28", "bold"), fill = "Light Goldenrod Yellow", justify = CENTER, text = "Instructions", tag = "htp") 
     self.canvas2.create_text(400, 300, font = ("Arial", "14", "bold"), fill = "Light Goldenrod Yellow", width = 600, justify = CENTER, tag = "htp", text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque dictum, erat ut dignissim sollicitudin, lorem neque molestie erat, a interdum justo nulla sed erat. Aliquam eu adipiscing nibh, in viverra diam. Cras dapibus lectus sed nibh lacinia eleifend. Duis a massa purus. Mauris vel turpis eu diam pharetra auctor ut ut tellus. Curabitur eget justo id sapien molestie egestas. Ut at nibh magna. Quisque id augue vitae nisl viverra tristique vel at eros. Pellentesque id risus lorem. Nullam aliquet eros tellus, a eleifend magna vehicula sit amet. Phasellus dapibus vulputate turpis, quis mattis justo consectetur sed. Curabitur porttitor vulputate eros.") 
     self.menu_button1 = Button(self.initial_frame, text = "Back to Menu", font = ("Arial", "18", "bold"), width = 25,bg = "Light Goldenrod Yellow", command = self.go_to_menu) 
     self.menu_button1.pack() 
     self.canvas2.create_window(400, 550, window=self.menu_button1, tag = "htp") 



    def create_settings(self): 
     self.create_bg() 


    def go_to_menu(self): 
     self.initial_frame.pack_forget() 
     self.canvas2.delete("all") 
     self.create_menu() 


    def quit_program(self): 
     self.parent.destroy() 


if __name__ == '__main__': 
    root = Tk() 
    math_program = GUI(root) 
    root.title("Mathematics Program") 
    root.mainloop() 

回答

2

问题在于self.canvas2

当你点击(1) “如何玩”,然后(2) “返回菜单”,然后(3) “如何玩”,这里发生了什么self.canvas2

  1. 你创建一个新的Canvas对象,将它分配给参考self.canvas2pack它。
  2. 您清除所有来自Canvas项目由self.canvas2
  3. 您创建一个新的Canvas对象,将其分配给参考self.canvas2,并pack它引用。

注意,从步骤(1),也就是现在的空白,因为你已经清除了所有的项目,仍然存在由于self.initial_frame一个孩子,即使你不再有本地引用它原来的画布对象,并且实际上处于您希望看到的新对象的顶部并阻止该对象的视图。

的快速解决方案是增加一个destroy呼吁摆脱未使用Canvas对象当您从How to Play帧切换出来:

def go_to_menu(self): 
    self.initial_frame.pack_forget() 
    self.canvas2.destroy() #### Get rid of the old unneeded canvas 
    self.create_menu() 

就个人而言,我认为这是更自然的重用旧Canvas对象,而不是每次切换到如何播放框架时删除并重新创建它,但因为它可以以任何方式工作,所以我想这是一个品味问题。

+0

非常感谢,这解决了我的问题。 – Campop

+0

不客气。如果这解决了您的问题,请考虑将其标记为接受的答案,方法是单击复选标记,以便其他人可以看到问题已解决。 – Brionius