2015-06-18 98 views
-1

所以我使用Python 3.4和tkinter。標籤不斷出現

當我再次調用一個包含標籤的函數時,標籤會一直出現在窗口中,但之前的標籤不會消失?

一旦函數被調用,我怎樣從GUI窗口中刪除任何打印標籤,然後顯示新標籤?

下面是代碼: -

#def prestart(): 
    #here I check if number of match is okay, if not, user is redirected to setting else, I call start() 

def start(): 

    #CPU Choice 
    cpu_choice = Label(historyframe, text = "CPU Choosed: {}".format(dict['cpu_choice'])) 

    #Played Match 
    #played_num_of_match = Label(scoreframe, text = "Number of Matches Played: {}".format(int(dict['match_played']))) 

    #Display Status 
    status_disp = Label(scoreframe, text = "Current Status: {}".format(dict['status'])) 

    if(int(dict['match_played']) < int(dict['num_of_match'])): 
     playframe.grid(row = 1, column = 0) 
     historyframe.grid(row = 2, column = 1) 
     status_disp.pack(fill=X) 
    elif(int(dict['match_played']) == int(dict['num_of_match'])): 
     playframe.grid(row = 1, column = 0) 
     historyframe.grid(row = 2, column = 1) 
     status_disp.pack(fill=X) 
     cp = dict['cpu_point'] 
     up = dict['user_point'] 
     result(cp, up) 
    cpu_choice.pack(fill = X) 
    scoreframe.grid(row = 2, column = 0) 

此功能只更新顯示!

def send_value(x): 
    #Here I run logic of game and change value of key in dictionary and call start() at end of change. 

現在,選擇按鈕沒有任何定義,因爲它們不需要再次被再次調用n。我只是讓播放幀消失而出現! 下面是代碼爲他們: -

#Display Question 
question = Label(playframe, text = "Rock? Paper? Scissor?") 

#Rock 
rock = Button(playframe, text = "Rock!", command = lambda: send_value("ROCK")) 

#Paper 
paper = Button(playframe, text = "Paper!", command = lambda: send_value("PAPER")) 

#Scissor 
scissor = Button(playframe, text = "Scissor!", command = lambda: send_value("SCISSOR")) 

所以,當用戶點擊搖滾/紙/剪刀,我只是在字典改變鍵值!但是如果我將標籤保留在功能之外,它不會自動更新!

其他一切都很完美。我現在開始讓代碼更清潔。

+1

爲什麼不更新現有標籤中的文本?另外,顯示一些代碼。 –

+0

你只是試圖更新標籤?你爲什麼在一個函數中創建它? – maccartm

+0

請向我們展示一個說明問題的MCVE。 –

回答

1

嘗試這樣的事情,而不是每次都創建一個新的標籤:

import Tkinter as tk 

class Window(): 

    def __init__(self, root): 

     self.frame = tk.Frame(root) 
     self.frame.pack() 

     self.i = 0 
     self.labelVar = tk.StringVar() 
     self.labelVar.set("This is the first text: %d" %self.i) 

     self.label = tk.Label(self.frame, text = self.labelVar.get(), textvariable = self.labelVar) 
     self.label.pack(side = tk.LEFT) 

     self.button = tk.Button(self.frame, text = "Update", command = self.updateLabel) 
     self.button.pack(side = tk.RIGHT) 

    def updateLabel(self): 

     self.i += 1 
     self.labelVar.set("This is new text: %d" %self.i) 


root = tk.Tk() 
window = Window(root) 
root.mainloop() 

要點:

1)一類是使用,因爲它是很容易來回傳遞值時,所有Tkinter對象和變量都是成員變量,可以從您的所有GUI功能訪問。

2)updateLabel不會創建新標籤。每次調用函數時,它都會更新StringVar()對象以保存新文本。這是在創建我的標籤小部件時用關鍵字textvariable = self.labelVar完成的。

PS:這是在Python 2.5的這樣做此代碼爲你工作,改變Tkintertkinter

編輯2015年6月19日

如果你想實現類似於我用你的代碼,沒有使用類的東西,你需要傳遞你的變量的引用。

1)更改start

您的標籤cpu_choicestatus_disp等應的功能之外創建的;可能在與question,rock,paper,scissors等相同的位置。您還將在函數外包裝它們。與start內部的.grid的所有呼叫相同;您不需要多次撥打packgrid:正確創建小部件時。

下列行:

playframe.grid(row = 1, column = 0) 
    historyframe.grid(row = 2, column = 1) 
    status_disp.pack(fill=X) 

能否功能以及外部進行;您在ifelif條件下執行這3條語句。這意味着它們不是真正的條件性陳述;無論條件的有效性如何,他們都會完成。

2)創建兩個cpu_choice & status_disp &編輯標籤如下(記得StringVar,功能費):

cpu_choice_text = StringVar() 
    cpu_choice_text.set("Set this to whatever is shown at the start of the game") 
    cpu_choice = Label(historyframe, text = cpu_choice_text.get(), textvariable = cpu_choice_text) 
    cpu_choice.pack(fill = X) 

    # And do this same thing for status_disp 

3)當你調用start,你現在將它傳遞cpu_choice_text & status_disp_text(或任何他們被稱爲)。而不是試圖更改標籤框架的text字段,您現在可以使用set呼叫StringVar它連接到標籤&該標籤將自動更新。例如:

def start(cpu_choice_text, status_disp_text): 
     cpu_choice.set(text = "CPU Choice: {}".format(dict['cpu_choice'])) 
     ... 

或者,把它包裝都在一個班,並通過對每一個變量Tkinter的部件&使用self使它更自己更容易。通過這種方式,您不需要將變量傳遞給函數,只需直接訪問成員變量,就像我在例子中使用self.i,self.labelVar一樣。

+2

更好的是,您可以刪除使用'StringVar'並直接更新標籤。這是你不得不管理的一個對象。 –

+0

請檢查代碼@BryanOakley –

+0

我使用.set和.get命令。我早先發現它,但通過您的代碼,我才瞭解如何使用它。但我並沒有創建一個班級。我可以面對什麼問題? –

0

每當您撥打start時,您都會創建新標籤並使用grid將它們放置在與舊標籤相同的位置。最好的解決方案是隻創建一次標籤,但如果您堅持每次調用start都要創建新標籤,則需要先刪除舊標籤。

您可以使用標籤的destroy()方法將其銷燬,但爲了達到這個目的,您必須保留標籤的全局引用。

+0

我真的很喜歡maccartm做的。但是IDK現在如何實現它。我目前正在處理它..我想我明白你的意思。我會試試看。因爲我認爲我已經試過了.. –

+0

它不起作用。摧毀後,我不能再回電了! –