1

我有一个函数,它从文本文件中读取位置,解析它们,然后使用 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-------')
4

1 回答 1

2

GUI 开发中一个非常好的经验法则是永远不要调用sleep. 这会冻结 GUI,即使只是几毫秒,它仍然是一个不好的做法。

在 Tkinter 中制作动画的正确方法是编写一个显示单帧的函数,然后使用after. 这允许事件循环在执行动画时不断地服务事件。

例如,将 for 语句的整个主体(减去 sleep)放入一个方法中。我们称之为“刷新”。让这个函数使用 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 重新绘制自身。

当然,您需要检查输入何时用尽,并且您可能希望用户可以通过请求动画停止的按钮设置一个标志等。

于 2013-04-25T17:33:25.287 回答