2016-01-23 117 views
-1

我正在編寫一個遊戲,其中包含從客戶端到服務器以及從服務器到客戶端的信息。一個特定的(非玩)客戶端是監視器,它只顯示遊戲板和玩家。這工作正常,唯一不起作用的是GUI上的退出按鈕。一件小事,但我希望它能工作。 :)另外,我認爲代碼可能存在某些問題,即使它有效。Tkinter按鈕沒有響應(沒有鼠標懸停效果)

我嘗試了各種不同的命令(sys.exit,quit ...)並沒有修復它。

沒有錯誤信息,按鈕根本沒有任何反應。沒有鼠標懸停效果,如果我點擊它,沒有任何效果相關的代碼(我刪除矩陣和服務器邏輯,因爲我認爲這是不相關的 - 如果不是我會後):

class Main(): 
def __init__(self, master): 
    self.frame = Frame(master) 
    self.frame.pack() 
    # Has to be counted up by server class 
    rounds = 0 
    # Has to be communicated by server class. If numberwin == numberrobots, 
    # game is won 
    numberwin = 0 
    numberrobots = 2 

def draw(self): 
    if hasattr(self, 'info'): 
     self.info.destroy() 
    if hasattr(self, 'quit'): 
     self.quit.destroy() 
    print "Main should draw this matrix %s" % self.matrix 

    [...] lots of matrix stuff [...] 

    # Pop-Up if game was won 
    # TODO: Make GUI quittable 
    if self.numberwin == self.numberrobots: 
     self.top = Toplevel() 
     self.msg = Message(self.top, text="This game was won!") 
     self.msg.pack(side=LEFT) 
     self.quittop = Button(
      self.top, text="Yay", command=self.frame.destroy) 
     self.quittop.pack(side=BOTTOM) 

    # TODO: Quit GUI 
    self.quit = Button(self.frame, text="Quit", command=self.frame.destroy) 
    self.quit.pack(side=BOTTOM) 

    # Information on the game 
    self.info = Label(
     self.frame, text="Rounds played: {}, Numbers of robots in win condition: {}".format(self.rounds, self.numberwin)) 
    self.info.pack(side=TOP) 


def canvasCreator(self, numberrows, numbercolumns): 
    # Game board 
    self.canvas = Canvas(
     self.frame, width=numbercolumns * 100 + 10, height=numberrows * 100 + 10) 
    self.canvas.pack() 


class Agent(Protocol, basic.LineReceiver): 
master = Tk() 
main = Main(master) 
# So first matrix is treated differently from later matrixes 
flagFirstMatrix = 1 

def connectionMade(self): 
    msg = dumps({"type": "monitor"}) 
    self.sendLine(msg) 
    print "Sent message:", msg 

def dataReceived(self, data): 
    # Decode the json dump 
    print "Data received: %s" % data 
    data = loads(data) 
    self.main.matrix = np.matrix(data["positions"]) 
    self.main.goals = np.matrix(data["goals"]) 
    self.main.next_move_by_agent = data["next_move"] 
    self.main.rounds = data["rounds"] 
    self.main.numberwin = data["win_states"] 
    if self.flagFirstMatrix == 1: 
     self.main.numberrows, self.main.numbercolumns = self.main.matrix.shape 
     self.main.canvasCreator(
      self.main.numberrows, self.main.numbercolumns) 
     self.main.canvas.pack() 
     self.flagFirstMatrix = 0 
    self.main.canvas.delete(ALL) 
    self.main.draw() 
    self.master.update_idletasks() 
    self.master.update() 
+2

它不會出現,你在任何地方調用'mainloop'整個線路的條款。這是真的,還是你離開了那個代碼? –

+0

不,我不是......我只是google了一下,顯然你必須調用主循環,即使沒有它顯示的東西:) 我只是嘗試了一些似乎符合邏輯的變體,但我無法弄清楚在哪裏調用mainloop和什麼。它在主人身上,因爲它是Tk()實例還是主要的?我應該在哪裏打電話? –

+0

通常,您將在根窗口上調用'mainloop'作爲程序中最後一行代碼。按鈕通過響應事件來工作。沒有事件循環運行,事件將無法發送或接收。 'mainloop'是事件循環。 –

回答

0

首先是類代理無壓痕,第二個爲退出按鈕的「呼叫返回「self.frame.destroy從來沒有定義,所以它不會做任何事情。如果你的意思是tkinter銷燬方法,請嘗試self.frame.destroy()或嘗試明確定義它。您也可以嘗試調用),要麼fram.pack_forget()fram.grid_forget()

添加master.mainloop(你的最後一行的代碼

+0

與上面相同的問題:我的最後一行是什麼?如果我把它作爲代理()中的最後一行,我會得到一個空的tk窗口。 –

+0

檢查我的編輯.. – idroid8

+0

謝謝你的回答,但是如果我這樣做,我再次得到一個空的tk窗口。我將它添加爲類代理中的最後一行,因爲只有那裏master是已知變量。它是在Agent中實例化的,所以我無法在課堂以外的地方使用它。我認爲你的意思是在別的地方? –