2015-06-19 214 views
0

我已经创建了一个顶层构件类,并希望它在窗口为'X'(关闭)时调用方法'close'。我得到错误 - 名称'close'未定义。当顶层窗口关闭时,有人能帮助我获得这种方法吗?为什么我的tkinter顶层“X”按钮超驰方法没有被调用?

代码聚焦:

class questions_window(): 
    def __init__(self, master): 
     self.master = master 
     self.master.geometry("300x300") 
     self.master.title("Questions") 
     self.master.protocol("WM_DELETE_WINDOW", close) 

    def focus(self): 
     self.master.attributes("-topmost", 1) 
     self.master.grab_set() 

    def close(self): 
     global paused 
     paused = False 
     self.master.grab_release() 
     self.master.destroy() 

全码:

from tkinter import * 

#starting velocity for the ball 
x_speed = 25 
y_speed = 25 
paused = False 

class questions_window(): 
    def __init__(self, master): 
     self.master = master 
     self.master.geometry("300x300") 
     self.master.title("Questions") 
     self.master.protocol("WM_DELETE_WINDOW", close) 

    def focus(self): 
     self.master.attributes("-topmost", 1) 
     self.master.grab_set() 

    def close(self): 
     global paused 
     paused = False 
     self.master.grab_release() 
     self.master.destroy() 

class table(): 
    '''This is the table class - the background for the game and it's drawings''' 
    def __init__ (self, window, colour = 'green', width=600, height = 400, score1 = 0, score2 = 0): 
     self. colour = colour 
     self.width = width 
     self.height = height 
     self.canvas = Canvas(window, bg=self.colour, height=self.height, width=self.width) 
     self.canvas.pack() 
     self.canvas.create_line(300, 0, 300, 400, fill="red") 
     self.score1 = score1 
     self.score2 = score2 

    #this recieves the coordinates of the ball and draws an oval based on these coordinates 
    #the instance of this item is returned to the ball class' 'circle' attribute 
    def draw_oval(self, oval): 
     x1 = oval.x_posn 
     x2 = oval.x_posn + oval.width 
     y1 = oval.y_posn 
     y2 = oval.y_posn + oval.height 
     c = oval.colour 
     return self.canvas.create_oval(x1, y1, x2, y2, fill=c) 

    #this recieves the coordinates of the paddle and draws a rectangle based on these coordinates 
    #the instance of this item is returned to the paddle class' 'rectangle' attribute 
    def draw_rectangle(self, rectangle): 
     x1 = rectangle.x_posn 
     x2 = rectangle.x_posn + rectangle.width 
     y1 = rectangle.y_posn 
     y2 = rectangle.y_posn + rectangle.height 
     c = rectangle.colour 
     return self.canvas.create_rectangle(x1, y1, x2, y2, fill=c) 

    #this method creates text on the canvas (the scores separated with a dash) 
    def reset_scorecard(self): 
     scores = str(self.score1) + " - " + str(self.score2) 
     self.scorecard = self.canvas.create_text(300, 50, font=("Purisa",40), text=scores) 

    #this finds out who has won a point and updates the scores on the canvas 
    def update_scorecard(self, player): 
     if player == 1: 
      self.score1 = self.score1 + 1 
     elif player == 2: 
      self.score2 = self.score2 + 1 
     scores = str(self.score1) + " - " + str(self.score2) 
     self.canvas.itemconfig(self.scorecard, text=scores) 

    #this method, when called, recieves a drawing object and updates its position on the canvas 
    def move_item(self, item, x1, y1, x2, y2): 
     self.canvas.coords(item, x1, y1, x2, y2) 

class ball(): 
    '''This is the ball class''' 
    def __init__(self, table, colour = 'red', width = 25, height = 25, x_speed = 15, 
               y_speed = 15, x_start = 5, y_start = 5): 
     self.colour = colour 
     self.width = width 
     self.height = height 
     self.x_posn = x_start 
     self.y_posn = y_start 
     self.table = table 
     self.x_start = x_start 
     self.y_start = y_start 
     self.x_speed = x_speed 
     self.y_speed = y_speed 
     self.circle = self.table.draw_oval(self) 

    #this method updates the ball's x and y coordinates by the speed values 
    #it then checks if the ball has hit any walls - if it has it 
    #reverses the x or y speeds depending on the wall it has hit 
    #it then moves the item to the new coordinates 
    def move_next(self): 
     self.x_posn = self.x_posn + self.x_speed 
     self.y_posn = self.y_posn + self.y_speed 
     if (self.x_posn <=3): 
      self.x_posn = 3 
      self.x_speed = -self.x_speed 
     if(self.x_posn >= (self.table.width - (self.width - 3))): 
      self.x_posn = (self.table.width - (self.width - 3)) 
      self.x_speed = -self.x_speed 
     if (self.y_posn <=3): 
      self.y_posn = 3 
      self.y_speed = -self.y_speed 
     if(self.y_posn >= (self.table.height - (self.height - 3))): 
      self.y_posn = (self.table.height - (self.height - 3)) 
      self.y_speed = -self.y_speed 
     x1 = self.x_posn 
     x2 = self.x_posn + self.width 
     y1 = self.y_posn 
     y2 = self.y_posn + self.height 
     self.table.move_item(self.circle, x1, y1, x2, y2) 

class paddle(): 
    '''This is the ball class''' 
    def __init__(self, master, table, colour = 'blue', width = 10, height = 110, 
                x_start = 0, y_start = 20): 
     self.colour = colour 
     self.width = width 
     self.height = height 
     self.x_posn = x_start 
     self.y_posn = y_start 
     self.table = table 
     self.master = master 
     self.x_start = x_start 
     self.y_start = y_start 
     self.rectangle = self.table.draw_rectangle(self) 

    #this method updates the paddles position on the screen 
    #it recieves the mouse' x and y positions and updates the y position 
    #of the paddle to match the y position of the mouse 
    #it then moves the paddle to the new coordinates 
    def move(self, event): 
     self.y_posn = event.y 
     x1 = self.x_posn 
     x2 = self.x_posn + self.width 
     y1 = self.y_posn 
     y2 = self.y_posn + self.height 
     self.table.move_item(self.rectangle, x1, y1, x2, y2) 

    #this method checks if the ball has moved passed the paddle 
    #if it has it will update the scorecard passing in the value of 2 
    #if it has BUT has done so between the top and bottom ends of the paddle 
    #it takes this as a paddle hit and updates score with 1 passed to the method 
    def paddle_collision(self, ball, master): 
     global switch_value 
     if ((self.x_posn + self.width) > ball.x_posn) and (self.y_posn < ball.y_posn < (self.y_posn + self.height)): 
      ball.x_speed = abs(ball.x_speed) 
      print("Yes!") 
      self.table.update_scorecard(1) 
     elif (self.x_posn+4) > ball.x_posn: 
      print("Collision") 
      self.table.update_scorecard(2) 
      pause() 
      question_win = Toplevel(self.master) 
      question_window = questions_window(question_win) 
      question_window.focus() 

#create the window object 
window = Tk() 
window.title("Tennis") 

#create the table, ball and paddle objects 
myTable = table(window) 
myTable.reset_scorecard() 
myBall = ball(table=myTable, x_speed = x_speed, y_speed = y_speed) 
paddle1 = paddle(table=myTable, master = window) 

#this is the animation loop which calls itself after every 40ms 
#each call calls the ball objects move_next method and the paddle's collision method 
def game_flow(): 
    if not paused: 
     myBall.move_next() 
     paddle1.paddle_collision(myBall,window) 
     window.after(40, game_flow) 

def pause(): 
    global paused 
    paused = True 

#first call of game_flow to start game 
game_flow() 

#binds the mouse events to the padde's move method 
window.bind("<Motion>", paddle1.move) 

window.mainloop() 
+1

'self.close':d – Jkdc

+0

哇 - 我是这样一个白痴!不能相信我错过了这个菜鸟的错误。完全值得我-1分!谢谢 – sw123456

回答

2

变化closeself.close

self.master.protocol("WM_DELETE_WINDOW", self.close) 
+0

我真是个白痴 - 我怎么会被卡在这里!谢谢! – sw123456

相关问题