简体   繁体   English

为什么未调用我的tkinter顶级“ X”按钮替代方法?

[英]Why is my tkinter toplevel 'X' button over-ride method not being called?

I have created a toplevel widget class and want to it to call the method 'close' when the window is 'X' (closed). 我创建了一个顶层小部件类,并希望当窗口为“ X”(关闭)时调用该方法的“关闭”方法。 I get the error - name 'close' not defined. 我收到错误-未定义名称“关闭”。 Could someone help me getting this method to run when the toplevel window is 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 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()

更改为close self.close

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM