老广东草包卷 2025-01-22 19:19 采纳率: 80%
浏览 54
已结题

如何让tkinter.Tk()实现等待若干秒的效果,使得tkinter不会因阻塞崩溃,并能阻塞后面代码的运行直到等待结束?

实际上有一种类似的方法,tkinter.Tk().after()。它能实现在若干秒后执行一个函数的效果,并且Tk()不会因线程阻塞而崩溃。
但是我想要的效果是在tkinter.Tk()等待(且不会崩溃)后再执行后面的程序。
比如下面这一段代码

import tkinter
def print_():
    print('b')
root = tkinter.Tk()
root.after(1000,print_)
print('a')

很容易就能猜到,运行结果是这样的:

a
b

其中b比a晚1s输出。
这意味着after()没有阻塞后面程序的运行。而我想要的效果恰好与之相反,就像这样:

b
a

其中过1s后,b和a几乎同一时间输出。并且因为print('a')被阻塞,b比a先被输出。
难道我只能绞尽脑汁地使用threading模块开多线程解决这个问题?
或者我只能傻乎乎地这样做?↓

import tkinter,time
root = tkinter.Tk()
for i in range(1000):
    time.sleep(0.001)
    root.update()
print('b')
print('a')

存在什么更好的办法吗?

  • 写回答

2条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    在Tkinter中,如果你想要让程序等待若干秒后再执行后面的代码,那么使用after()函数是最好的选择。这是因为Tkinter是基于事件驱动的,而不是基于线程或进程的。因此,你不能像在普通的Python程序中那样使用阻塞操作来暂停程序的执行。阻塞操作会导致Tkinter窗口无响应,这可能会导致程序崩溃。然而,Tkinter提供了一个事件循环机制来处理这种需求。

    你所描述的需求实际上是无法实现的。在Python中,你不能阻止一个已经开始的非阻塞操作。也就是说,一旦print('a')被调用并执行后,它就会立即执行完毕,不管你是否试图在另一个地方进行延迟操作。由于Python的异步非阻塞特性,这是无法避免的。即使你尝试使用time.sleep()来暂停程序的执行,它仍然不会改变已经发生的事实,因为Python不会真的暂停已经执行的线程。也就是说,你不能迫使print('a')在指定的延迟之后才被执行。

    然而,你可以通过调整你的代码结构来实现类似的效果。例如,你可以将需要等待的代码块封装在一个函数中,然后使用after()来延迟执行这个函数。这样,你可以控制哪些代码块会在延迟后执行。虽然这不是真正的阻塞后面的代码运行直到等待结束,但这是使用Tkinter实现类似效果的最佳方式。这就是你提到的使用after()函数的例子。在你的例子中,print('a')会在print('b')之前被执行,但两者的执行间隔会被推迟到设定的延迟时间之后。这并不是真正的阻塞后面的代码运行直到等待结束,但它在视觉上和用户感知上可能产生类似的效果。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 1月30日
  • 已采纳回答 1月22日
  • 创建了问题 1月22日