【问题标题】:time.sleep() Equivalent on Tkintertime.sleep() 在 Tkinter 上等效
【发布时间】:2016-01-15 12:00:39
【问题描述】:

我必须停止循环并在几秒钟后恢复。我尝试使用 after(),但循环不会冻结。当我使用 time.sleep() (解决 tkinter)时,tkinter 冻结。有另一种方式或功能等效 time.sleep() 没有冻结。

代码:

for message in listOfMessages:
    time.sleep(message.time)
    #manipulate message
    #change text widget

这将冻结我的 tkinter 应用程序。

我尝试使用 after() 但 message.time 是一个浮点数:0.5054564 到 1.5234244。这是随机的。而 after 只支持 int。我无法转换为 int,因为低数字会产生差异。如果我将 0.52342342 转换为 int: 523... 我失去了其他 42342

这也不起作用:

def changes(#values):
    #manipulate message
    #change text widget

for message in listOfMessages:
    app.after(message.time, lambda: changes(#values))

有另一个函数等效 time.sleep 不是冻结 tkinter 并且与 after() 不同?如果没有,还有其他方法可以做到这一点吗?感谢关注。

【问题讨论】:

  • message.time 代表什么——毫秒?秒?分钟?

标签: python python-3.x time tkinter


【解决方案1】:

创建一个类似物:

for message in listOfMessages:
    time.sleep(message.time)
    change(message)

tkinter:

def update_widget(app, messages):
    message = next(messages, None)
    if message is None: # end of the loop
        return
    delay = int(message.time * 1000) # milliseconds
    app.after(delay, change, message) # execute body
    app.after(delay, update_widget, app, messages) # next iteration

update_widget(app, iter(listOfMessages))

如果您想等到change(message) 完成后再继续循环:

def iterate(message, app, messages):
    change(message)
    update_widget(app, messages)

def update_widget(app, messages):
    message = next(messages, None)
    if message is None: # end of the loop
        return
    delay = int(message.time * 1000) # milliseconds
    app.after(delay, iterate, message, app, messages)

update_widget(app, iter(listOfMessages))

【讨论】:

  • 这可行,但是当消息有时间!= 0时,会出现错误:tkinter.TclError: bad argument "507.478125": must be cancel, idle, info, or an integer
  • @ArnaldoBadin:如果message.time 是浮点数,则将延迟强制转换为整数。我已经更新了答案。
  • Bug 出现,不是错误,但我有延迟消息。有办法self.after read float吗?喜欢 507.478125?
  • @ArnaldoBadin: 延迟以 毫秒 为单位,即调度精度可能比这更差,因此接受浮点数无论如何也无济于事。确保您不调用可能在change(message) 中阻塞的函数。使用线程、单独的进程来卸载阻塞调用。顺便说一句,你确定要等待 500 秒(差不多 10 分钟)吗?
  • @ArnaldoBadin:这表明问题在于您在代码中调用了阻塞函数。 Timer() 创建一个新线程,让您避免由于阻塞调用造成的不必要延迟。否则,没有理由期望 Timer() 的精度比 app.after() 的精度更高。
猜你喜欢
  • 2012-05-10
  • 1970-01-01
  • 2017-05-23
相关资源
最近更新 更多