2017-01-08 4 views
2

ボタンを押して2つのアクションをリンクしようとしています。私はスレッドを使用しています 1つの関数 'callback'はメッセージを出力し、もう1つは にgifアニメーションを表示するラベルを作成します。私がそれらをスレッドし、 を実行するためにボタンを押すと、gifは無限に(連続的に)表示されますが、私は をGUIから削除(削除)します。どんな助けもありがとうございます。tkinkterスレッドが終了していません(gifは無限ループで実行されます)

from tkinter import * 
from tkinter import ttk 
from tkinter import scrolledtext 
import threading 
import time 

root = Tk() 
root.title('Title') 

def callback(): 
    print('this message') 
    time.sleep(0.5) 

def animate(): 

    while True: 

     try: 

      time.sleep(0.04) 
      img = PhotoImage(file='path',format="gif - {}".format(num)) 
      label1 = ttk.Label(root, image=img) 
      label1.grid(row=0, column=1) 
      num+=1 

     except: 

      num=0 
def thr(): 

    t1= threading.Thread(target=callback) 
    t2= threading.Thread(target=animate) 
    t1.start() 
    t2.start() 

button = ttk.Button(root, text='click', command=thr).grid(row=0, column=1, sticky=N) 
entry = scrolledtext.ScrolledText(root, width=30, heigh=10, wrap=WORD) 
entry.grid(row=0, column=0) 

entry.focus() 
root.mainloop() 
+0

新しいラベルを何度も作成するのではなく、既存のラベルの画像を置き換えることができます。同じセルに何千ものラベルがあります。ところで、 'tkinter'は' thread'の代わりに 'thread.'の代わりに使う' root.after(milliseconds、function_name) 'という関数を持っています – furas

+0

' root = Tk() 'の前にすべての関数を置くことができるようにコードを読みやすくします – furas

+0

' if num> 10:break 'を実行して10個の画像の後にTrueを残し、スレッドを終了する。 – furas

答えて

0

variableを使用して、2番目のスレッドに最初のスレッドが終了したことを通知できます。

running = False 

しかし、それは最善の方法ではないことができます - 多分あなたは、むしろ別のスレッドからの情報を送信するためにモジュールqueueを使用する必要があります。

label1.destroy()を使用してラベルと画像を削除できますが、ラベルを1回だけ作成してからこのラベルの画像を変更する必要があります。

label1['image'] = img 

コード:

from tkinter import * 
from tkinter import ttk 
from tkinter import scrolledtext 
import threading 
import time 
#from PIL import Image, ImageTk # for `png` 

# --- functions ---- 

def callback(): 
    # inform function to use external/global variable because you use `=` 
    global running 

    print('callback: start') 
    time.sleep(2) 
    print('callback: end') 

    # inform other thread to end running 
    running = False 

def animate(): 
    print('animate: start') 

    while running: 
     try: 
      time.sleep(0.04) 
      img = PhotoImage(file='path', format="gif - {}".format(num)) 
      #img = Image.open('test/image-{}.png'.format(num)) # for `png` 
      #img = ImageTk.PhotoImage(img) # for `png` 
      #label1.img = img # solution for garbage collector problem # for `png` 
      label1['image'] = img 
      num += 1 
     except: 
      num = 0 

    #label1.img = None # doesn't work 
    #label1['image'] = None # doesn't work 

    # destroy label 
    label1.destroy() 

    print('animate: end') 

def thr(): 
    # inform function to use external/global variable because you use `=` 
    global running 
    global label1 

    # create new label 
    label1 = ttk.Label(root) 
    label1.grid(row=0, column=1) 

    running = True 

    t1 = threading.Thread(target=callback) 
    t2 = threading.Thread(target=animate) 
    t1.start() 
    t2.start() 

# --- main --- 

# create global variables 
running = False 
label1 = None 

# - GUI - 

root = Tk() 
root.title('Title') 

button = ttk.Button(root, text='click', command=thr) 
button.grid(row=0, column=1, sticky=N) 

entry = scrolledtext.ScrolledText(root, width=30, heigh=10, wrap=WORD) 
entry.grid(row=0, column=0) 

entry.focus() 
root.mainloop() 

EDIT:あなたも

while t1.is_alive(): 

代わりのwhile running:


を使用することができます

編集:また、root.afterは2番目のスレッドでは使用できません。

from tkinter import * 
from tkinter import ttk 
from tkinter import scrolledtext 
import threading 
import time 
#from PIL import Image, ImageTk # for `png` 

# --- functions ---- 

def callback(): 
    # inform function to use external/global variable because you use `=` 
    global running 

    print('callback: start') 
    time.sleep(2) 
    print('callback: end') 

def animate(num=0): 
    try: 
     img = PhotoImage(file='path', format="gif - {}".format(num)) 
     #img = Image.open('test/ball-{}.png'.format(num)) # for `png` 
     #img = ImageTk.PhotoImage(img) # for `png` 
     #label1.img = img # solution for garbage collector problem # for `png` 
     label1['image'] = img 
     num += 1 
    except: 
     num = 0 

    if t1.is_alive(): 
     # execute again after 4ms 
     root.after(4, animate, num) # 4ms = 0.04s 
    else: 
     # destroy label 
     label1.destroy() 
     print("animate: end") 


def thr(): 
    # inform function to use external/global variable because you use `=` 
    global label1 
    global t1 

    # create new label 
    label1 = ttk.Label(root) 
    label1.grid(row=0, column=1) 

    t1 = threading.Thread(target=callback) 
    t1.start() 

    print("animate: start") 
    animate(0) 

# --- main --- 

# create global variables 
label1 = None 
t1 = None 

# - GUI - 

root = Tk() 
root.title('Title') 

button = ttk.Button(root, text='click', command=thr) 
button.grid(row=0, column=1, sticky=N) 

entry = scrolledtext.ScrolledText(root, width=30, heigh=10, wrap=WORD) 
entry.grid(row=0, column=0) 

entry.focus() 
root.mainloop() 
+0

ねえ、ありがとう!朝にこの最初のことを試してみましょう、私はあなたに知らせるでしょう! –

+0

2番目のスレッドの代わりに 'root.after'を使って例を追加しました – furas

+0

これはうまくいくと思います。お知らせします!本当にありがとう! –

関連する問題