我有一个函数从文本文件中读取位置,解析它们,然后使用coords函数将相应的对象移动到tkinter画布上列出的位置。正在从文件中读取数据并正确解析但由于某种原因,coords函数仅将对象移动到循环的最后一次迭代中文件中列出的最后位置。
在循环的每次迭代之后,我是否需要以某种方式更新画布?谢谢!
这是我的代码:
def playback():
fptr = tkFileDialog.askopenfilename()
filename = open(fptr,"rU")
if not filename:
return
stat.set('REPLAY IN PROGRESS')
gamestatus[0] = 2
for line in filename:
line = line.strip()
#Example line from input file: 'B:#,#,#,#|L:#,#,#,#|R:#,#,#,#'
line = line.split('|')
B_loc = line[0].split(':')[1].split(',')
L_loc = line[1].split(':')[1].split(',')
R_loc = line[2].split(':')[1].split(',')
#Converting strings to ints and lists to tuples to simplify code below
B_tup=(int(B_loc[0]),int(B_loc[1]),int(B_loc[2]),int(B_loc[3]))
L_tup=(int(L_loc[0]),int(L_loc[1]),int(L_loc[2]),int(L_loc[3]))
R_tup=(int(R_loc[0]),int(R_loc[1]),int(R_loc[2]),int(R_loc[3]))
#Moving objects to locations from input file
playingField.coords(pongball.ball,B_tup)
playingField.coords(leftpaddle.paddle,L_tup)
playingField.coords(rightpaddle.paddle,R_tup)
time.sleep(.02)
filename.close()
gamestatus[0] = 0
stat.set('-------Pong-------')
答案 0 :(得分:2)
GUI开发中一个非常好的经验法则是永远不要调用sleep
。这会冻结GUI,即使只是几毫秒,它仍然是一个不好的做法。
在Tkinter中执行动画的正确方法是编写一个显示单个帧的函数,然后使用after
重新安排自己。这允许事件循环在进行动画时不断地为事件服务。
例如,取整个for语句 - 减去睡眠 - 并将其放入方法中。我们称之为“刷新”。让这个功能使用after重新安排自己,如下所示:
def refresh():
line = get_next_line()
line = line.split('|')
B_loc = line[0].split(':')[1].split(',')
...
# call this function again in 20ms
root.after(20, refresh)
现在你需要做的就是实现get_next_line
作为一个功能而你已经设置好了。每次更新坐标时,这将自动允许GUI重绘自己。
当然,您需要检查输入何时用尽,并且您可能希望通过请求动画停止的按钮等设置用户可以设置的标记。