gpt4 book ai didi

python - 在主循环旁边运行 Tkinter 相关代码,无需 GUI 卡住

转载 作者:行者123 更新时间:2023-12-01 05:37:20 26 4
gpt4 key购买 nike

我正在编写一个简单的图像查看器,它可以让用户快速浏览数万张图像,一次大约 100 张。图像是磁盘上的文件。

为了使查看器正常工作,它必须在用户当前图像之前连续预加载图像(否则查看器将变得异常缓慢)。

我用来在 Tkinter 标签网格中显示图像的基本方法如下(这已经过测试并且有效):

def load_image(fn):
image = Image.open(fn)
print "Before photoimage"
img = ImageTk.PhotoImage(image)
print "After photoimage"

label.config(image=load_image("some_image.png")

我需要 ImageTk.PhotoImage 实例来在标签上显示图像。我实现了两种不同的方法,每种方法都有一个相关的问题。

第一种方法:启动一个单独的线程来预加载图像:

def load_ahead():
for fn in images:
cache[fn] = load_image()
threading.Thread(target=load_ahead).start()
top.mainloop()

这在我的 Linux 机器上运行得很好。然而,在另一台机器上(恰好运行Windows,并使用pyinstaller编译),似乎发生了死锁。打印“Before Photoimage”,然后程序卡住,这表明加载器线程在创建 ImageTk.PhotoImage 对象时卡住了。 ImageTk.PhotoImage 对象的创建必须发生在主(Tkinter 主循环)线程内吗?创建 PhotoImage 的计算成本是否昂贵,或者与实际从磁盘加载图像相比可以忽略不计?

第二种方法:为了规避从 Tkiner 的主循环线程内创建 PhotoImage 对象的可能要求,我求助于 Tk.after:

def load_some_images():
#load only 10 images. function must return quickly to prevent freezing GUI
for i in xrange(10):
fn = get_next_image()
cache[fn] = load_image(fn)
top.after_idle(load_some_images)

top.after_idle(load_some_images)

这样做的问题是,除了产生额外的开销(即图像加载过程必须分解成非常小的 block ,因为它与 GUI 竞争)之外,它还会在调用期间定期卡住 GUI ,并且它似乎消耗了执行期间发生的任何键盘事件。

第三种方法有没有办法可以检测待处理的用户事件?我怎样才能完成这样的事情?

def load_some_images():
while True:
try: top.pending_gui_events.get_nowait()
except: break
#user is still idle! continuing caching of images
fn = get_next_image()
cache[fn] = load_image(fn)
top.after_idle(load_some_images)

top.after(5,load_some_images)

编辑:我尝试使用 top.tk.call('after','info') 来检查待处理的键盘事件。这并不总是可靠的,并且界面仍然缓慢/无响应。

提前感谢您的任何想法

最佳答案

我建议创建一个 load_one_image 函数,而不是 load_some_images 函数。它不太可能干扰事件循环。

此外,根据经验,通过 after_idle 调用的函数不应使用 after_idle 自行重新安排。原因是 after_idle 将阻塞,直到空闲事件队列被清空。如果在处理队列时不断向队列添加内容,则队列永远不会完全耗尽。这可能就是为什么你的 GUI 在使用第二种方法时似乎偶尔会挂起的原因。

尝试 after(5, ...) 而不是 after_idle(...)。如果您的系统可以在不到 5 毫秒的时间内创建一个图像,那么您可以在大约半秒内处理 100 个图像,这可能足以提供一个非常敏捷的界面。您可以调整延迟,看看它如何影响应用程序的整体感觉。

关于python - 在主循环旁边运行 Tkinter 相关代码,无需 GUI 卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18606229/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com