2014-01-14 118 views
0

我創建了一個按鈕,當它被點擊時調用我的main_menu函數,但它只能被點擊一次。當它被點擊時,它將使用戶回到主菜單,但是如果用戶離開主菜單並再次點擊它,它什麼也不做。爲什麼我的按鈕只能在Python中工作一次?

def __init__(self): 
    self.main = main 
    self.main.grid() 

    <Really long tuple declared here> 

    self.main_menu() 

def main_menu(self): 
    self.main.grid_remove() 
    main = Frame(root) 
    self.main = main 
    self.main.grid() 

    self.sort_button = Tkinter.Button(main, text = "Sort the list using the bubble sort method", command = self.sort_choice) 

    <Some more buttons coded here> 

    self.sort_button.pack() 


def sort_choice(self): 
    self.main.grid_remove() 
    main = Frame(root) 
    self.main = main 
    self.main.grid() 

    <Some other buttons and messages coded here> 

    self.main_menu.pack() 

我該如何讓一個按鈕工作多次?

+0

在我看來,你並沒有真正掌握GUI應該如何在Tk中完成 - 似乎很奇怪,你反覆創建並移除'grid'和'main'。你的應用程序應該如何運作?你能發佈整個可運行代碼嗎? – Fenikso

+0

另外,您至少有一個全局名稱'main',一個類成員'main'和幾個本地名'main'。很混亂。這可能是不正確的:'self.main_menu.pack()',你正試圖調用'self'的函數'pack'。main_menu',但'self.main_menu'是'self'的成員函數,似乎沒有這樣的函數屬性。 – Nabla

+0

我剛剛意識到我犯的錯誤。該按鈕與其功能具有相同的名稱。我對Tkinter很陌生,所以我可能犯了很多錯誤,並且我正在爲編程類做這些。我的老師也是Tkinter的新手,所以我只知道我在網上看到的東西。非常感謝! – JeremyM

回答

1

正如註釋中所述,發佈的代碼並不表示預期的行爲,可能應該更改代碼的整個結構(以及使用適當的命名)。我試圖清除一些概念,但是這個答案不會使這個代碼有效(甚至可能不可執行)。

如果您正在使用全局變量(我假設主要應該是一個全局變量),當你想改變你需要全球結構來聲明它們的函數內的值。否則,在函數中更改全局變量的值將會創建一個具有相同名稱的局部變量,並且不會影響全局變量。

下面是簡單的代碼片段,以清除此:

val = "x"         

def use_global():       
    print "Global value is: %s" % val   

def change_global_wrong():     
    print "changing global in change_global_wrong" 
    val = "y"        
    print "global in change_global_wrong is: %s" % val 

def change_global_correct():    
    global val        
    print "changing global in change_global_correct" 
    val = "y"        
    print "global in change_global_correct is: %s" % val                                                      

use_global() 
change_global_wrong() 
use_global()     
change_global_correct() 
use_global() 

因此改變價值主要內的功能實際上是創建將要超出範圍則返回每個功能時局部變量。 這意味着唯一的參考你必須框架,是self.main。所以我建議註冊爲按鈕的父項。

self.sort_button = Tkinter.Button(self.main, text = "Sort the list using the bubble sort method", command = self.sort_choice) 

即使這樣,通過調用self.main.grid_remove()要刪除的Frame對象。這會導致Frame(及其子部件)被刪除。在這裏,我增加了對傳統知識的應用程序代碼示例(和上的評論符合規定,包括一種方式來打破它):

#!/usr/bin/env python 
import datetime 
from Tkinter import * 

class MyApp(object): 
    def __init__(self): 
     self.root = Tk() 
     self.time_var = StringVar() 
     self.time_var.set('...') 
     self._init_widgets() 

    def _init_widgets(self): 
     self.label = Label(self.root, textvariable=self.time_var) 
     frame = Frame(self.root) 
     self.frame = frame 
     self.button = Button(frame, text = "update time", command = self._on_button_click) 
     self.frame.grid() 
     self.button.grid() 
     self.label.grid() 

    def _on_button_click(self): 
     self.time_var.set(str(datetime.datetime.now())) 
     # uncomment these lines to get a broken code 
     #self.frame.grid_remove() 
     #self.frame = Frame(self.root) 
     #self.frame.grid() 

    def run(self): 
     self.root.mainloop() 

if __name__ == '__main__': 
    app = MyApp() 
    app.run() 

現在,如果你取消註釋錯誤行,你會看到,調用grid_remove( )刪除了Frame,但創建了一個新的Frame對象(並將其分配給相同的引用)並不能幫助我們恢復。因爲有一個很好的按鈕的舊框架已經消失了。而更新時間的好按鈕也隨其父母一起消失。

我不確定這個問題中的代碼是否實際運行(因爲它缺少上下文和其他行),但是如果它運行,我期待這個,因爲通過點擊按鈕,主要的框架小部件被刪除的按鈕也應該從小部件中刪除(創建一個新的框架不應該恢復按鈕)。因爲這沒有發生(正如你所說的按鈕正在顯示,但沒有運行),我得出結論在這裏貼的代碼行並沒有正確表達你的情況。但是,我希望這些代碼示例能夠幫助您更多地瞭解您的應用程序。

+0

感謝您的幫助,這爲我解決了一些事情。 – JeremyM