Python tkinter:具有不同运动模式的对象

Python tkinter:具有不同运动模式的对象,python,class,object,tkinter,Python,Class,Object,Tkinter,我正在做一个模拟,在这个模拟中,同一类的一些立方体随机移动。我的目标是给他们另一个移动模式,当他们满足一些特征(例如他们的对象编号)时 我的问题是: 如果它们符合特征,我如何“关闭”第一个移动模式并激活下一个 下面是一个非常简化的模拟示例,以及它是如何工作的: from tkinter import * from random import * class Cubes: def __init__(self, master, canvas, number, x1, y1, color)

我正在做一个模拟,在这个模拟中,同一类的一些立方体随机移动。我的目标是给他们另一个移动模式,当他们满足一些特征(例如他们的对象编号)时

我的问题是: 如果它们符合特征,我如何“关闭”第一个移动模式并激活下一个

下面是一个非常简化的模拟示例,以及它是如何工作的:

from tkinter import *
from random import *


class Cubes:
    def __init__(self, master, canvas, number, x1, y1, color):
        self.master = master
        self.canvas = canvas
        self.number = number
        self.x1 = x1
        self.y1 = y1
        self.x2 = x1 + 15
        self.y2 = y1 + 15
        self.color = color
        self.rectangle = canvas.create_rectangle(x1, y1, self.x2, self.y2, fill=color)

    def movement(self):
        self.x = randint(-10, 10)
        self.y = randint(-10, 10)
        canvas.move(self.rectangle, self.x, self.y)
        if self.number == 2:
            def movementII(self):
                canvas.move(self.rectangle, 0, 0)
            self.canvas.after(100, self.movementII)
        self.canvas.after(100, self.movement)


if __name__ == "__main__":
    master = Tk()
    canvas = Canvas(master, width=900, height=600)
    canvas.pack()
    master.title("Simulation")
    cube = Cubes(master, canvas, 2, randint(50, 800), randint(25, 500), "black")
    cube.movement()

mainloop()
如何“关闭”第一个移动模式并激活下一个移动模式

当您在之后调用
时,它将返回一个唯一标识符。您可以保存该标识符,然后在\u cancel
之后将其传递到
,以取消尚未运行的作业

我不完全清楚您想要什么,但是如果您想在切换到新的移动时关闭旧的移动,它将如下所示:

class Cubes:
    def __init__(self, master, canvas, number, x1, y1, color):
        ...
        self.after_id = None
        ...

    def cancel(self):
        if self.after_id is not None:
            self.after_cancel(self.after_id)
            self.after_id = None

    def movement(self):
        self.x = randint(-10, 10)
        self.y = randint(-10, 10)
        canvas.move(self.rectangle, self.x, self.y)

        if self.number == 2:
            def movementII(self):
                canvas.move(self.rectangle, 0, 0)
            self.cancel()
            self.after_id = self.canvas.after(100, self.movementII)

        self.after_id = self.canvas.after(100, self.movement)   
def move(self):
    if self.number == 1:
        self.movement_1()
    elif self.number == 2:
        self.movement_2()

    self.canvas.after(100, self.move)

def movement_1(self):
    self.x = randint(-10, 10)
    self.y = randint(-10, 10)
    canvas.move(self.rectangle, self.x, self.y)

def movement_2(self):
    canvas.move(self.rectangle, 0, 0)
更好的方法可能是在
之后使用
调用一个方法,它只调用适当的方法

例如,类似这样的内容:

class Cubes:
    def __init__(self, master, canvas, number, x1, y1, color):
        ...
        self.after_id = None
        ...

    def cancel(self):
        if self.after_id is not None:
            self.after_cancel(self.after_id)
            self.after_id = None

    def movement(self):
        self.x = randint(-10, 10)
        self.y = randint(-10, 10)
        canvas.move(self.rectangle, self.x, self.y)

        if self.number == 2:
            def movementII(self):
                canvas.move(self.rectangle, 0, 0)
            self.cancel()
            self.after_id = self.canvas.after(100, self.movementII)

        self.after_id = self.canvas.after(100, self.movement)   
def move(self):
    if self.number == 1:
        self.movement_1()
    elif self.number == 2:
        self.movement_2()

    self.canvas.after(100, self.move)

def movement_1(self):
    self.x = randint(-10, 10)
    self.y = randint(-10, 10)
    canvas.move(self.rectangle, self.x, self.y)

def movement_2(self):
    canvas.move(self.rectangle, 0, 0)
然后,要切换移动方法,只需更改
self.number
,它将在适当的时间自动调用。

通用小部件方法返回一个整数“after identifier”,如果要取消回调,可以将该整数传递给
after\u cancel()
方法。因此,这就是如何将它们“关闭”的方法。要拥有一个可变的移动模式,您需要将其抽象出来,并将其作为
Cube
类的属性。