python - Why is my tkinter toplevel 'X' button over-ride method not being called? -
i have created toplevel widget class , want call method 'close' when window 'x' (closed). error - name 'close' not defined. me getting method run when toplevel window closed?
code in focus:
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()
full code:
from tkinter import * #starting velocity 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 table class - background game , 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 coordinates of ball , draws oval based on these coordinates #the instance of item returned 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 coordinates of paddle , draws rectangle based on these coordinates #the instance of item returned 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 canvas (the scores separated 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 has won point , updates scores on 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 drawing object , updates position on canvas def move_item(self, item, x1, y1, x2, y2): self.canvas.coords(item, x1, y1, x2, y2) class ball(): '''this 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 ball's x , y coordinates speed values #it checks if ball has hit walls - if has #reverses x or y speeds depending on wall has hit #it moves item 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 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 paddles position on screen #it recieves mouse' x , y positions , updates y position #of paddle match y position of mouse #it moves paddle 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 ball has moved passed paddle #if has update scorecard passing in value of 2 #if has has done between top , bottom ends of paddle #it takes paddle hit , updates score 1 passed method def paddle_collision(self, ball, master): global switch_value if ((self.x_posn + self.width) > ball.x_posn) , (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 window object window = tk() window.title("tennis") #create table, ball , 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 animation loop calls after every 40ms #each call calls ball objects move_next method , 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 start game game_flow() #binds mouse events padde's move method window.bind("<motion>", paddle1.move) window.mainloop()
change close
self.close
self.master.protocol("wm_delete_window", self.close)
Comments
Post a Comment