2017-07-09 77 views
0

我正在寫一個簡單的小餅圖遊戲來熟悉Python和Tkinter。我有一個讓玩家輪到的按鈕,但是我一直在困擾着如何讓電腦輪到它。Python/Tkinter:延遲後更新按鈕文本

這將對計算機採取反過來,但不會更新lbl_btn文本直到deal()的回報,也就是說,我從來沒有看到卡那人打:

lbl_btn = Button(root, textvariable=varCard, command=lambda: slap()).pack() 
deal_btn = Button(root, text="deal", command=lambda: deal()).pack() 

def deal(): 
    varTurn.get() % 2 == 0 
    pile.append(human.deck[0]) 
    human.deck.remove(human.deck[0]) 
    update_label() 
    root.after(2000) 
    pile.append(compy.deck[0]) 
    compy.deck.remove(compy.deck[0]) 
    update_label() 


def update_label(): 
    varTurn.set(varTurn.get()+1) 
    print(pile[len(pile)-1].name) 
    varCard.set(pile[len(pile)-1].name) 

這的deal()版本顯示每個按鈕後點擊正確的標籤,但不是最優的,因爲電腦又需要一個單獨的點擊:

def deal(): 
if varTurn.get() % 2 == 0: 
    pile.append(human.deck[0]) 
    human.deck.remove(human.deck[0]) 
else: 
    pile.append(compy.deck[0]) 
    compy.deck.remove(compy.deck[0]) 
varTurn.set(varTurn.get()+1) 
print(pile[len(pile)-1].name) 
varCard.set(pile[len(pile)-1].name) 

我知道標籤按鈕不更新,直到我的拉姆達完成,但在這種情況下,如何ç我會在延遲後創建一個單獨的電話deal,這將導致更新lbl_btn的值?

回答

0

如果我明白你在問什麼,你可能會在尋找Tk.update()。如果您在root.after(2000)之前調用root.update(),則會執行強制刷新並導致Tkinter更新UI。

爲例(我修改您的代碼):

from Tkinter import * 

deck1 = ['A', 'B', 'C'] 
deck2 = ['D', 'E', 'F'] 
pile = [] 

def deal(): 
    varTurn.get() % 2 == 0 
    pile.append(deck1[0]) 
    deck1.remove(deck1[0]) 
    update_label() 
    root.update() 
    root.after(2000) 
    pile.append(deck2[0]) 
    deck2.remove(deck2[0]) 
    update_label() 


def update_label(): 
    varTurn.set(varTurn.get()+1) 
    print(pile[len(pile)-1]) 
    varCard.set(pile[len(pile)-1]) 

root = Tk() 
varCard = StringVar() 
varTurn = IntVar() 
lbl_btn = Button(root, textvariable=varCard, command=lambda: slap()).pack() 
deal_btn = Button(root, text="deal", command=lambda: deal()).pack() 
root.mainloop() 

這將導致新卡繪製後,頂部的按鈕文本被立即刷新。請注意,這最終可能不是實現遊戲的最佳方式,因爲即使按鈕​​更新以顯示新卡,在等待deal()函數完成時,GUI也將不響應。

+0

兩個計數都正確。這確實會產生我正在查找的更新行爲,並且也會使按鈕無響應,直到deal()返回。有關如何重組的想法?我已經考慮過多線程計算機的轉變和「巴掌」機制(這將是我的另一個第一個...) – nwhaught

+0

您可能需要考慮在調用after()後添加第二個參數。看看這個問題[這裏](https://stackoverflow.com/questions/25753632/tkinter-how-to-use-after-method)。這樣,你可以將你的交易邏輯分成兩個函數,並在相同的兩秒鐘後調用計算機處理函數,但是在等待期間你會控制回tkinter主循環。請記住,如果用戶在兩秒內過期之前再次點擊交易,則必須處理髮生的情況,因此會變得更加複雜。讓我知道這是否有幫助。 –