使用 Tkinter 快速显示图像
Rapidly Display Images With Tkinter
我正在寻找一种使用 tkinter 快速 显示图像的有效方法,我的意思是非常快。目前我有这个代码:
from tkinter import*
import threading
import time
root = Tk()
root.geometry("200x200")
root.title("testing")
def img1():
threading.Timer(0.2, img1).start()
whitei = PhotoImage(file="white.gif")
white = Label(root, image=whitei)
white.image = whitei
white.place(x=0, y=0)
def img2():
threading.Timer(0.2, img2).start()
blacki = PhotoImage(file="black.gif")
black = Label(root, image=blacki)
black.image = blacki
black.place(x=0, y=0)
img1()
time.sleep(0.1)
img2()
root.mainloop()
本质上,代码只显示黑白图像,但它使我的 CPU 处于 100% 使用率,并且无论我将每张图片的显示时间设置得多么短,它都非常慢。有没有更快、更有效的方法来做到这一点?
如前所述,我建议使用 after
。你真的不应该在你的主线程之外改变任何 tkinter 对象。此外,每次都创建一个新对象并不是最有效的。这是我会尝试的东西:
import tkinter as tk
root = tk.Tk()
root.geometry("200x200")
root.title("testing")
whitei = tk.PhotoImage(file="white_.gif")
blacki = tk.PhotoImage(file="black_.gif")
label = tk.Label(root, image=whitei)
label.image1 = whitei
label.image2 = blacki
label.place(x=0, y=0)
time_interval = 50
def img1():
root.after(time_interval, img2)
label.configure(image=whitei)
def img2():
root.after(time_interval, img1)
label.configure(image=blacki)
root.after(time_interval, img1)
root.mainloop()
您不需要使用线程。第二,除非你在一个单独的线程中使用 sleep()
,否则你不应该在 tkinter 应用程序中使用睡眠。 sleep()
中断主循环并导致 tkinter 冻结,直到睡眠结束。这在 99.9% 的情况下不是您想要的,因此您应该对任何定时事件使用 after()
。
您可以简单地为每个图像创建每个标签,然后使用跟踪变量将正确的标签提升到顶部。
这是一个简单的例子。
from tkinter import *
root = Tk()
root.geometry("200x200")
root.title("testing")
current_image = ""
black_image = PhotoImage(file="black.gif")
white_image = PhotoImage(file="white.gif")
black_label = Label(root, image=black_image)
white_label = Label(root, image=white_image)
black_label.image = black_image
white_label.image = white_image
black_label.grid(row=0, column=0)
white_label.grid(row=0, column=0)
def loop_images():
global current_image, black_image, white_image
if current_image == "white":
black_label.tkraise(white_label)
current_image = "black"
else:
white_label.tkraise(black_label)
current_image = "white"
root.after(100, loop_images)
loop_images()
root.mainloop()
我正在寻找一种使用 tkinter 快速 显示图像的有效方法,我的意思是非常快。目前我有这个代码:
from tkinter import*
import threading
import time
root = Tk()
root.geometry("200x200")
root.title("testing")
def img1():
threading.Timer(0.2, img1).start()
whitei = PhotoImage(file="white.gif")
white = Label(root, image=whitei)
white.image = whitei
white.place(x=0, y=0)
def img2():
threading.Timer(0.2, img2).start()
blacki = PhotoImage(file="black.gif")
black = Label(root, image=blacki)
black.image = blacki
black.place(x=0, y=0)
img1()
time.sleep(0.1)
img2()
root.mainloop()
本质上,代码只显示黑白图像,但它使我的 CPU 处于 100% 使用率,并且无论我将每张图片的显示时间设置得多么短,它都非常慢。有没有更快、更有效的方法来做到这一点?
如前所述,我建议使用 after
。你真的不应该在你的主线程之外改变任何 tkinter 对象。此外,每次都创建一个新对象并不是最有效的。这是我会尝试的东西:
import tkinter as tk
root = tk.Tk()
root.geometry("200x200")
root.title("testing")
whitei = tk.PhotoImage(file="white_.gif")
blacki = tk.PhotoImage(file="black_.gif")
label = tk.Label(root, image=whitei)
label.image1 = whitei
label.image2 = blacki
label.place(x=0, y=0)
time_interval = 50
def img1():
root.after(time_interval, img2)
label.configure(image=whitei)
def img2():
root.after(time_interval, img1)
label.configure(image=blacki)
root.after(time_interval, img1)
root.mainloop()
您不需要使用线程。第二,除非你在一个单独的线程中使用 sleep()
,否则你不应该在 tkinter 应用程序中使用睡眠。 sleep()
中断主循环并导致 tkinter 冻结,直到睡眠结束。这在 99.9% 的情况下不是您想要的,因此您应该对任何定时事件使用 after()
。
您可以简单地为每个图像创建每个标签,然后使用跟踪变量将正确的标签提升到顶部。
这是一个简单的例子。
from tkinter import *
root = Tk()
root.geometry("200x200")
root.title("testing")
current_image = ""
black_image = PhotoImage(file="black.gif")
white_image = PhotoImage(file="white.gif")
black_label = Label(root, image=black_image)
white_label = Label(root, image=white_image)
black_label.image = black_image
white_label.image = white_image
black_label.grid(row=0, column=0)
white_label.grid(row=0, column=0)
def loop_images():
global current_image, black_image, white_image
if current_image == "white":
black_label.tkraise(white_label)
current_image = "black"
else:
white_label.tkraise(black_label)
current_image = "white"
root.after(100, loop_images)
loop_images()
root.mainloop()