【问题标题】:Tkinter understanding after()Tkinter 理解 after()
【发布时间】:2015-05-24 10:24:49
【问题描述】:

首先,在这里看看我之前的帖子:Tkinter understanding mainloop

遵循那里的建议后,在 GUI 编程中,必须不惜一切代价避免无限循环,以保持小部件对用户输入的响应。

而不是使用:

while 1:
    ball.draw()
    root.update()
    time.sleep(0.01)

我在 draw() 函数中使用 self.canvas.after(1, self.draw) 进行了管理。

所以我的代码现在看起来像这样:

# Testing skills in game programming

from Tkinter import *

root = Tk()
root.title("Python game testing")
root.resizable(0, 0)
root.wm_attributes("-topmost", 1)

canvas = Canvas(root, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
root.update()

class Ball:
    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_oval(10, 10, 25, 25, fill=color)
        self.canvas.move(self.id, 245, 100)

        self.canvas_height = canvas.winfo_height()
        self.x = 0
        self.y = -1

    def draw(self):
        self.canvas.move(self.id, self.x, self.y)

        pos = self.canvas.coords(self.id)
        if pos[1] <= 0:
            self.y = 1
        if pos[3] >= self.canvas_height:
            self.y = -1

        self.canvas.after(2, self.draw)


ball = Ball(canvas, "red")
ball.draw()

root.mainloop()

但是,self.canvas.after() 中的时间无法正常工作... 如果设置为 1,则非常快!如果设置为 10、5 甚至 2,那就太慢了! 在我的代码中使用上述 while 循环时,我没有遇到这个问题,因为 time.sleep() 可以正常工作!


编辑:

我现在可以报告 Tkinter 的 after 函数内的时间在我的 Windows 8.1 平板电脑和我的 Windows 8.1 笔记本电脑中无法正常工作,而在同一台笔记本电脑上通过 虚拟机运行 Ubuntu 它确实可以正常工作。

【问题讨论】:

  • sleep 中的时间以秒为单位,但after 中的时间为毫秒。使用after(10,...) 似乎和使用sleep(0.01) 一样快。到底是什么问题?
  • 无法重现。无论我输入after(2,...) 还是after(20,...),我肯定看到了不同
  • 2 秒 1 毫秒?对我来说,该设置大约需要 1/2 秒!这是意料之中的,因为球每次迭代移动一个像素,并且帧高 500 像素。你那边好像有什么很奇怪的东西……
  • 现在在我的笔记本电脑上 14 秒,而使用 1 毫秒...天哪!!!我也会在我的 linux 上运行它..
  • 我现在可以报告 Tkinter 的 after 函数内的时间在我的 win8.1 平板电脑和我的 win8.1 笔记本电脑中无法正常工作,而在同一台笔记本电脑上通过虚拟运行 ubuntu 时机器它确实可以正常工作!!! :O

标签: python tkinter windows-8.1 tkinter-canvas


【解决方案1】:

对象(画布)的速度和时钟/循环速度应该被视为两个不同的东西,恕我直言。 因此,您可以在 2ms 甚至更大(例如 10...25...

...
self.canvas.after(2, self.draw)
... # loop this after 2 ms.

同时,根据“多少像素”来改变速度:

pos = self.canvas.coords(self.id)
    if pos[1] <= 0:
        self.y = 20
    if pos[3] >= self.canvas_height:
        self.y = -20

所以调整这些值,然后:

self.canvas.move(self.id, 245, 100)

可以让您微调红点的位置和速度。 希望对你有帮助

【讨论】:

    【解决方案2】:

    time.sleep 中的时间以秒为单位,而 after() 中的时间以毫秒为单位。 time.sleep(0.01) 与 self.canvas.after(10, self.draw) 相同。如果 after(2, func) 太慢但 after(1, func) 太快,那么您可以尝试 sleep(0.0005) 然后 after(1, func) 确实会延迟 1.5 毫秒,但几乎看不到。无论哪种方式,都要调整时间,直到暂停正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-16
      • 1970-01-01
      • 2015-05-23
      • 1970-01-01
      • 2020-11-17
      • 2014-11-03
      • 2020-09-12
      • 1970-01-01
      相关资源
      最近更新 更多