Tkinter画布上尝试从另一个类进行更新时出错

问题描述 投票:-1回答:1

我已经用Python编写了自己的2048游戏版本。当我从它的主类执行它时,它工作得很好:

class _2048:
    def __init__(self):
    ...
...
...
test = _2048()

该类还具有Tkinter和Tkinter.Canvas对象,还有另一个名为Tile的类,在该类中,我具有相对于每个单个tile的所有功能。

现在,我正在尝试编写一个自动控制游戏的类。让我解释一下:在2048类中,我绑定了上,下,右和左箭头键。它们共享相同的回调函数,在这里我使用event.keycode值来决定要做什么。为了模拟此事件,我创建了一个名为Kevent的类,如下所示:

class Kevent:
    def __init__(self, mov):
        if(mov=="n"):
            self.keycode = 38
        elif(mov=="s"):
            self.keycode = 40
        elif(mov=="e"):
            self.keycode = 39
        elif(mov=="w"):
            self.keycode = 37

(我知道那不是很漂亮)。最后,我有Test类,其中有_2048类的实例和Kevent类的实例:

class Test:
    joc: _2048
    event: Kevent
    def __init__(self):
        self.joc = _2048()
        self.event = Kevent("s")
        sleep(1)
        self.joc.tecla(self.event)
test = Test()

当我运行上面的代码时,它什么也没有发生,但是当我关闭2048窗口时,出现以下错误:

    self.tk.call((self._w, 'move') + args)
_tkinter.TclError: invalid command name ".!canvas"

它在此函数内部(在Tile类内部)失败,在其中我将2048的Canvas中的元素移动到该位置:

    def mou_canvas(self, canvas):
        # moviment is a class where I control the moves of the "self" tile
        moviment = self.moviment
        # quadrat is the Canvas id for the square of the tile
        quadrat = self.getQuadrat()
        # text is the Canvas id for the text inside the tile
        text = self.getText()

        (dx,dy) = moviment.getMov()
        score = 0

        # If the tile can move
        if(moviment.getPot_moure()):
            canvas.move(quadrat, 100*dx, 100*dy)  # <---- The error occurs in this line
            canvas.move(text, 100*dx, 100*dy)
            canvas.update_idletasks()

        # If there is a collision
        if(moviment.getColisiona()):
            mult = moviment.getMult_colisio()
            if(mult == 0):
                canvas.delete(quadrat)
                canvas.delete(text)
            else:
                score = self.getNum()*2
                self.setNum(score)
                canvas.tag_raise(quadrat)
                canvas.tag_raise(text)
                fontsize = 30 if(score<1024) else 20 if(score<100000) else 15
                canvas.itemconfig(text, text=str(self.getNum()), font=("Arial Black", fontsize))

        self.moviment.reset()

        return score

我想解决方案必须非常简单,但是我花了几个小时解决了这个问题,但是还没有发现。

编辑:我通过在新线程中执行_2048类来解决问题:

class _2048(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()
    def run(self):
        # Everything I had in old __init__ method
        ...
...
...
python tkinter
1个回答
0
投票

我通过在新线程中执行_2048类解决了这个问题:

class _2048(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.start()
    def run(self):
        # Everything I had in old __init__ method
        ...
...
...
© www.soinside.com 2019 - 2024. All rights reserved.