Python Tkinter框在重新绘制时移动

时间:2012-03-12 00:59:30

标签: python tkinter game-physics

我有一个程序通过销毁它然后再次绘制它来重新绘制Tkinter画布。但是,每次绘制框时,它都会移动几个像素到屏幕右侧。例如,如果第一个框被刷新到屏幕的左侧,大约10个左右绘制,它现在与屏幕的右侧齐平。造成这种情况的原因是什么?如何阻止它?

请注意,我在Mac上运行这一切,并且我在Tkinter中应该有效的东西遇到了麻烦,所以如果您知道这是问题,请告诉我。感谢您的帮助,如果您需要任何其他信息,请随时索取!

按照布莱恩·奥克利的建议,我不再有框架被破坏,只有矩形。但是,现在我遇到的问题是框架被绘制并且永远是空的......我不明白为什么。

代码:     我改变了一点,以适应布莱恩奥克利的建议。现在我在TclError: invalid command name ".4332933704"

处收到错误w.create_rectangle(x, y, z, a, fill="white")
def printBoard(time,board):
    global w
    global root
    x=20
    y=15
    z=60
    a=45
    for i in range(len(board)-3,-1,-1):
        y+=30
        a+=30
        x=20
        z=60
        for j in range(len(board[i])):
            x+=40
            z+=40
            if len(board[i][j])==0:    
                w.create_rectangle(x, y, z, a, fill="white")
            else:
                w.create_rectangle(x, y, z, a, fill='black')
    root.after(int(time*1000),tech)

def tech():
    global w
    w.delete(ALL)

def output(board,difficulty):
    global root
    global w
    root=Tk()
    root.lift()
    root.title('Tetris')
    w = Canvas(root, width=500, height=750)
    w.bind_all('<Up>',rotate)
    w.bind_all('<Left>',left)
    w.bind_all('<Right>',right)
    w.bind_all('<Escape>',stop)
    w.pack()
    mainloop()
    global playing
    playing=True
    printBoard(sec,board)
    while playing:
        play(board)
        printBoard(sec,board)

2 个答案:

答案 0 :(得分:1)

在对原始代码进行一系列编辑后,我正在撰写此答案。修复代码的唯一方法是完全重写代码,而这不是本论坛的用途。

我建议你停止处理你的程序并完成关于Tkinter的几个教程(tkdocspythonware是很好的起点)。您对事件驱动编程存在根本性的误解。例如,您在调用mainloop后有代码,但调用mainloop需要是程序中最后一行逻辑代码。事实上,您尝试在导致最新错误的mainloop退出后创建小部件(TclError:无效命令名称“.4332933704”)

其次,你的程序中有一个无限循环。事件驱动程序已经以事件循环的形式存在无限循环。那就是mainloop。拥有自己的无限循环只是错误的做事方式。您的程序需要基于事件,而不是硬编码的无限循环。

如果要每N毫秒触发一次重绘,可以使用after tkinter方法来安排将来调用的函数。如果该函数做同样的事情(即:将来某个时候调用自己),你内置了一个简单的动画循环。例如:

class MyApp(...):
    def __init__(...):
        # call it the first time; it will then call 
        # itself several times a second
        self.redraw()

    def redraw(self, *args):
        <redraw everything>
        self.after(42, self.redraw)

答案 1 :(得分:0)

您的第一个问题是您在每次迭代时重新初始化整个GUI。 Tkinter不是那样设计的。这样做会产生不可预测的结果。您应该只创建一个Tk的实例!并且只需拨打mainloop一次。

“盒子”每次移动的事实可能与此有关,如果用“盒子”表示窗口。如果您没有指定位置,则每次创建窗口时,某些windw管理器都会执行此操作。

此外,删除和重新创建小部件是非常不寻常的 - 至少它是缓慢而低效的。有用于移动对象的画布命令,或者如果您确实需要,可以删除并重新创建画布项。