Быстро отображать изображения с помощью Tkinter - PullRequest
0 голосов
/ 04 января 2019

Я ищу эффективный способ быстрого отображения изображений с помощью 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()

По сути, код просто отображает черно-белое изображение, но он загружает мой процессор на 100% и работает довольно медленно, независимо от того, как мало я делаю количество времени, в течение которого отображается каждое изображение. Есть ли более быстрый и эффективный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Вам не нужно использовать многопоточность. Во-вторых, если вы не используете sleep() внутри отдельного потока, вы никогда не должны использовать 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()
0 голосов
/ 04 января 2019

Как уже упоминалось, я бы предложил использовать 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()
...