3

ですから、私が求めていることは、私のかなり長い主題からわかると思いますが、繰り返します。バックグラウンドのスレッドがTKinterで計算を実行しているときに、gifをアニメーション化しようとしています。簡単にするために、私はこのgifを使用しています:http://i.imgur.com/4Y9UJ.gif

スクリプトを実行するとわかるように、gifアニメーションは現在機能しています。ただし、[生成]ボタンが押されてスレッドが開始されるとすぐに、gifは終了するまで一時停止します。私はtime.sleep()を使用して、バックグラウンドで実行する大量の計算をシミュレートしています(ただし、これが実際に問題の原因であるかどうかはわかりません)。

アニメーションがどのように機能しているかを正確に理解していないことと関係があると確信しています。何かアドバイス?

次のようにコーディングします。

from Tkinter import *
import tkMessageBox
import time
import os
import threading
from PIL import Image, ImageTk

class Gif(Label):
    def __init__(self, master, filename):
        evanGif = Image.open(filename)
        gifSeq = []
        try:
            while 1:
                gifSeq.append(evanGif.copy())
                evanGif.seek(len(gifSeq)) # skip to next frame
        except EOFError:
            pass # we're done
        try:
            #Special case for the evangalion gif
            if evanGif.info['duration'] == 0:
                self.delay = 100
            else:
                self.delay = evanGif.info['duration']
        except KeyError:
            self.delay = 100
        gifFirst =gifSeq[0].convert('RGBA')
        self.gifFrames = [ImageTk.PhotoImage(gifFirst)]

        Label.__init__(self, master, image=self.gifFrames[0])

        temp =gifSeq[0]
        for image in gifSeq[1:]:
            temp.paste(image)
            frame = temp.convert('RGBA')
            self.gifFrames.append(ImageTk.PhotoImage(frame))

        self.gifIdx = 0
        self.cancel = self.after(self.delay, self.play)

    def play(self):
        self.config(image=self.gifFrames[self.gifIdx])
        self.gifIdx += 1
        if self.gifIdx == len(self.gifFrames):
            self.gifIdx = 0
        self.cancel = self.after(self.delay, self.play)

class App:
    generating = False
    def __init__(self, master):
        self.master=master

        #Initializing frames
        self.buttonFrame = Frame(master, background='light gray')
        self.loadingFrame = Frame(master, background='light gray')
        self.loadingFrame.grid(row=0)
        self.buttonFrame.grid(row=1)
        self.anim = Gif(self.loadingFrame, '4Y9UJ.gif').pack()
        self.update_Thread = threading.Thread(target=time.sleep, args=(5,))
        self.buttonSetup()

    def buttonSetup(self):
        #ALL THE BUTTONS
        self.generateBt = Button(self.buttonFrame, text="Generate!", command=self.generate, background='light gray', highlightbackground='light gray')
        self.generateBt.pack(side=LEFT)
        self.quitBt = Button(self.buttonFrame, text="Quit!", fg="red", command=self.buttonFrame.quit, background='light gray', highlightbackground='light gray')
        self.quitBt.pack(side=LEFT)

    def generate(self):
        self.hideForGen()
        self.update_Thread.start()
        while(self.update_Thread.isAlive()):
            self.master.update_idletasks()
        self.reset()
        self.master.update_idletasks()
        tkMessageBox.showinfo("Complete", "Report generation completed!")

    def hideForGen(self):
        self.buttonFrame.grid_forget()

    def reset(self):
        self.buttonFrame.grid(row=1)

root = Tk()
root.title('Test')
root.configure(background='light gray')
app = App(root)
root.mainloop()
4

2 に答える 2

1

以下の方法で:

    def generate(self):
        self.hideForGen()
        self.update_Thread.start()
        while(self.update_Thread.isAlive()):
            self.master.update_idletasks()
        self.reset()
        self.master.update_idletasks()
        tkMessageBox.showinfo("Complete", "Report generation completed!")

入れたら

    self.master.update()

それ以外の

    self.master.update_idletasks()

動作するはずです。少なくとも私にとってはそうだった。

于 2012-07-17T11:37:20.013 に答える
1

問題はgenerate()メソッドにあります。そのwhileループは不要です。

スレッドを再開することはできないことに注意してください。生成ボタンを複数回使用する場合は、毎回新しいスレッドを作成する必要があります。

class App:
    generating = False
    def __init__(self, master):
        self.master=master

        #Initializing frames
        self.buttonFrame = Frame(master, background='light gray')
        self.loadingFrame = Frame(master, background='light gray')
        self.loadingFrame.grid(row=0)
        self.buttonFrame.grid(row=1)
        self.anim = Gif(self.loadingFrame, '4Y9UJ.gif')
        self.anim.pack()
##        self.update_Thread = threading.Thread(target=time.sleep, args=(5,))

        self.buttonSetup()

    def buttonSetup(self):
        #ALL THE BUTTONS
        self.generateBt = Button(self.buttonFrame, text="Generate!", command=self.generate, background='light gray', highlightbackground='light gray')
        self.generateBt.pack(side=LEFT)
        self.quitBt = Button(self.buttonFrame, text="Quit!", fg="red", command=self.buttonFrame.quit, background='light gray', highlightbackground='light gray')
        self.quitBt.pack(side=LEFT)

    def wait_generate(self):
        if self.update_Thread.isAlive():
            self.master.after(500, self.wait_generate)
        else:
            tkMessageBox.showinfo("Complete", "Report generation completed!")
            self.reset()

    def generate(self):
        self.hideForGen()
        self.update_Thread = threading.Thread(target=time.sleep, args=(5,))
        self.update_Thread.start()
##        while(self.update_Thread.isAlive()):
##            self.master.update_idletasks()
##        self.reset()
##        self.master.update_idletasks()
##        tkMessageBox.showinfo("Complete", "Report generation completed!")
        self.wait_generate()

    def hideForGen(self):
        self.buttonFrame.grid_forget()

    def reset(self):
        self.buttonFrame.grid(row=1)
于 2012-07-17T22:26:18.093 に答える