Многопоточность Progressbar и GIF одновременно в Tkinter - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь создать поток анимации GIF, который я поместил в виджет Tkinter и индикатор выполнения, чтобы они запускались одновременно при выполнении сценария. После этого я хотел бы использовать time.sleep(10), чтобы они запускались одновременно в течение 10 секунд, а затем остановка индикатора выполнения с помощью progressbar.stop(). Мой код ниже:

import tkinter
from tkinter import ttk
from tkinter import *
import time
from PIL import Image, ImageTk
from itertools import count
import threading


def main_fun():

    global progressbar, lbl
    window = tkinter.Tk()
    window.geometry("390x600")  # Width x Height

    # progress bar
    progressbar = ttk.Progressbar(None)  # ttk is method inside tkinter
    progressbar.config(orient="horizontal",
                       mode='indeterminate', maximum=100, value=0)
    progressbar.pack(side=TOP)

    # gif image class
    class ImageLabel(tkinter.Label):
        """a label that displays images, and plays them if they are gifs"""

        def load(self, im):
            if isinstance(im, str):
                im = Image.open(im)
            self.loc = 0
            self.frames = []

            try:
                for i in count(1):
                    self.frames.append(ImageTk.PhotoImage(im.copy()))
                    im.seek(i)
            except EOFError:
                pass

            try:
                self.delay = im.info['duration']
            except:
                self.delay = 100

            if len(self.frames) == 1:
                self.config(image=self.frames[0])
            else:
                self.next_frame()

        def unload(self):
            self.config(image=None)
            self.frames = None

        def next_frame(self):
            if self.frames:
                self.loc += 1
                self.loc %= len(self.frames)
                self.config(image=self.frames[self.loc])
                self.after(self.delay, self.next_frame)

    lbl = ImageLabel(window)
    lbl.pack(anchor="center")
    lbl.load(
        'C:/Users/*****/test.gif')

    # thread the label with the gif
    t = threading.Thread(target=lbl, args=(None,))
    t.start()

    window.mainloop()


main_fun()


progressbar.start(8)  # 8 is for speed of bounce
t = threading.Thread(target=progressbar, args=(None,)
                     )  # thread the progressbar
#t.daemon = True
t.start()

time.sleep(10)  # 10 second delay, then progressbar must stop
progressbar.stop()

Я не знаком с потоками и поэтому не понимаю, что делаю неправильно. Я получаю ошибки:

TypeError: объект 'ImageLabel' не может быть вызван

TypeError: объект 'progressbar' не может быть вызван

Пожалуйста, помогите.

1 Ответ

1 голос
/ 28 марта 2019

Вы можете использовать ответ , данный здесь , для реализации индикатора выполнения в другом потоке. Кроме того, с тем, что вы сделали, было неправильно, что ваш progressbar не является вызываемым объектом и не переопределяет метод run() .

...