2016-01-23 118 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中实例化的,所以我无法在课堂以外的地方使用它。我认为你的意思是在别的地方? –