使用sleep()时,Python中的代码移动不顺畅

使用sleep()时,Python中的代码移动不顺畅,python,python-3.x,Python,Python 3.x,编写了一个函数,可以在循环中将矩形左右移动到边上。 我希望它以恒定的速度移动。实际发生的是运动很粗糙。 运动会改变速度。 我怎样才能使它以恒定的速度移动 def btn_start_press(): global x1, x2, y1, y2, canvas_width size = int(entry_size.get()) x2 = x1 + size y2 = y1 + size label_size["text"] = size * 2

编写了一个函数,可以在循环中将矩形左右移动到边上。 我希望它以恒定的速度移动。实际发生的是运动很粗糙。 运动会改变速度。 我怎样才能使它以恒定的速度移动

def btn_start_press():
    global x1, x2, y1, y2, canvas_width

    size = int(entry_size.get())
    x2 = x1 + size
    y2 = y1 + size
    label_size["text"] = size * 2

    forward = True
    while True:
        if forward:
            x1 += 1
            x2 += 1
        else:
            x1 -= 1
            x2 -= 1
        if x2 + size >= canvas_width:
            forward = False
        elif x1 <= 0 :
            forward = True

        time.sleep(0.005)
        canvas.coords(rect,x1,y1,x2,y2)
        canvas.update()
def btn_start_press():
全局x1、x2、y1、y2,画布宽度
size=int(entry\u size.get())
x2=x1+尺寸
y2=y1+尺寸
标签大小[“文本”]=大小*2
向前=真
尽管如此:
如果转发:
x1+=1
x2+=1
其他:
x1-=1
x2-=1
如果x2+尺寸>=画布宽度:
向前=错误

elif-x1我想这不是时间问题,而是视觉不流畅。你有没有试过在没有可视化的情况下打印步骤

您正在尝试每秒更新画布200次。这似乎很重要。我们看到一个平滑的运动,每秒25-60帧

更新:


我真的需要动作这么快,甚至更快。除了多次更新画布之外,还有没有其他方式来表示运动

您仍然可以快速更改您的值,但如果眼睛看不到任何差异,则不需要如此频繁的视觉更新。您可以尝试的是每10步更新一次帧


但更好的做法是异步运行计算和可视化,因为无论可视化过程需要多长时间,您可能需要的是两个步骤之间的固定时间。

在您的计算机中,除了代码之外,还有很多事情在进行,这意味着您的代码并不是争夺资源的唯一因素。在您的例子中,循环在每次迭代中花费的时间并不相同,因此,循环最终会以锯齿状运动结束。在您的情况下,睡眠时间也很低,这将占用分配给应用程序的大量时间

在这种情况下,一个简单的解决方案可能会很好地工作,那就是使用两次重画之间经过的时间,并使用该时间计算按钮移动的距离

如果使用
time.sleep(0.015)
你的应用程序将尝试以大约75 fps的速度运行它的代码(减去花在代码中的时间)。您可以使用
time.time()
获取当前时间(以毫秒为单位)。请注意,此时间信息可能相当粗糙,并且存在其他问题(例如,如果调整了计算机的时钟,则会发生更改)。有,但是对于这个用例,它应该足够好了

pixels_per_second = 100
previous_time = time.time()

while True:
    new_time = time.time()
    elapsed = new_time - previous_time
    pixels = pixels_per_second * elapsed

    if forward:
        x1 += pixels
        x2 += pixels
    else:
        x1 -= pixels
        x2 -= pixels

    if x2 + size >= canvas_width:
        forward = False
    elif x1 <= 0 :
        forward = True

    previous_time = new_time

    canvas.coords(rect,x1,y1,x2,y2)
    canvas.update()

    time.sleep(0.015)
像素每秒=100
上一次时间=time.time()
尽管如此:
新建时间=time.time()
已用时间=新的\u时间-上一个\u时间
像素=每秒像素数*经过时间
如果转发:
x1+=像素
x2+=像素
其他:
x1-=像素
x2-=像素
如果x2+尺寸>=画布宽度:
向前=错误

elif x1我确实需要动作这么快,甚至更快。除了多次更新画布外,有没有其他方法来表示运动?在现代,以200 Hz的频率更新显示器一点也不过分。@Acorn当然取决于用例。对于GUI应用程序来说,完全没有必要用200hz更新ui,而对于游戏来说,这是有意义的。我怀疑60和200hz之间有什么区别,但我想这是另一个讨论。让我们同意,我们不是在谈论高端视频游戏或电影:)@MatsLindh不,我是在谈论显示器,而不是更新backbuffer/canvas/对于给定应用程序的任何内容是否有用。由于日程安排和它如何实现的限制,不能保证时间
sleep()
处于睡眠状态。它可能更长,在旧的Python版本上甚至更短。谢谢,这似乎是可行的,但是速度以指数级的速度加速。添加了这一行:上一次时间=新时间您是否忘记包含
上一次时间=新时间