【问题标题】:.after not functioning as I would have expected.在没有按我预期的那样运作之后
【发布时间】:2019-11-04 08:10:27
【问题描述】:

我正在使用 .after 来调用在我的 GUI 内移动图像的函数。当我运行代码并调用函数“myFunc”时,图像确实会移动,但它会立即发生。它应该逐渐在屏幕上移动。我不确定为什么会这样。

def movRight():
    global img
    global imgx
    canvas.move(imgx,20,0)
    return

def myFunc():
    moveController(1,20)
    return

def moveController(extruder, position):
    global e1current
    global e2current
    global e3current
    global e4current


    if extruder == 1:
            while position > e1current:
                print("moving")
                e1current+=1
                main.after(500,movRight)

            return

【问题讨论】:

  • 您正在同时调度movRight()(其中position - e1current)的所有实例;所有这些都在 500 毫秒后快速连续发生。你需要做的是调用movRight()一次,如果没有到达最终位置,让它安排另一个调用自己。

标签: python python-3.x tkinter


【解决方案1】:

.after 不会阻止循环的执行。它更像是产生一个单独的线程,该线程在 500(在您的情况下)毫秒后开始执行。换句话说,.after 不会阻塞循环 500ms,调用 movRight 然后继续循环。看看这个例子:

import tkinter as tk

def print_hi():
    print("hi")

root = tk.Tk()
for i in range(5):
    root.after(1000, print_hi)
print("loop done")
root.mainloop()

这会输出“循环完成”,然后,大约一秒钟后,它会打印五次“hi”。

【讨论】:

    【解决方案2】:

    考虑这段代码:

    while position > e1current:
        main.after(500,movRight)
    

    就像你这样写一样:

    main.after(500,movRight)
    main.after(500,movRight)
    main.after(500,movRight)
    ...
    

    由于调用main.after(500,movRight) 可能会在毫秒左右执行,因此您将排队数百或数千个调用,这些调用都将在未来执行 500 毫秒。

    换句话说,这与您这样做没有什么不同:

    def something():
        movRight()
        movRight()
        movRight()
        ...
    main.after(500,something)
    

    制作动画的正确方法是创建一个执行一帧动画的函数,然后自行重新调度。

    例如:

    def moveController():
        movRight()
        e1current+=1
        if position > e1current:
            main.after(500, moveController)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2021-01-16
      • 1970-01-01
      • 2016-06-19
      相关资源
      最近更新 更多