我有一个程序通过销毁它然后再次绘制它来重新绘制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)
答案 0 :(得分:1)
在对原始代码进行一系列编辑后,我正在撰写此答案。修复代码的唯一方法是完全重写代码,而这不是本论坛的用途。
我建议你停止处理你的程序并完成关于Tkinter的几个教程(tkdocs和pythonware是很好的起点)。您对事件驱动编程存在根本性的误解。例如,您在调用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管理器都会执行此操作。
此外,删除和重新创建小部件是非常不寻常的 - 至少它是缓慢而低效的。有用于移动对象的画布命令,或者如果您确实需要,可以删除并重新创建画布项。