2011-06-28 61 views
0

,所以我有這樣的代碼:擺脫線程內的標籤?

import thread 
from Tkinter import * 
import random 
import time 
Admin=Tk() 
def moveit(number): 
    songas=Label(Admin,text=number,bg='red') 
    def ji(): 
     plad=0.0 
     recount=0 
     times=0 
     while 1: 
      plad-=0.1 
      recount+=1 
      times+=1 
      time.sleep(0.5) 
      pls=0.0 
      pls+=plad 


      if recount==4: 

       pls=0 
       plad=0.0 
       recount=0 

      songas.place(relx=pls,rely=0.7) 


    thread.start_new_thread(ji,()) 
za=random.random() 

button=Button(Admin,text='Press',command=lambda:moveit(str(za))) 
button.place(relx=0.2) 
Admin.mainloop() 

,它開始向左移動,但如果你再次按下「按下」按鈕,它把對舊的基礎上增加一些更多的數字。 是否有人知道如何清除舊數字,以便只有知道的人才能清除舊數字?

回答

1

的Tkinter不是線程安全的 - 你不能在任何線程操作部件除了主要的一個,或者你會得到未定義的結果。

你不需要線程。你的代碼增加了一個無限循環,但是應用程序已經有了一個無限循環(事件循環),你可以利用它。

如果你想移動一些項目創建一個功能,做兩件事情。首先,它可以做任何你想要的,比如移動物品。其次,它使用標準的after方法在短時間內(例如,半秒或500毫秒)再次調用自己。這樣,您可以讓事件循環驅動動畫,不需要線程,而且UI保持響應。

下面是一個例子。我懷疑這確實是你想要的,因爲我不確定你想要什麼。

import Tkinter as tk 
import random 

class SampleApp(tk.Tk): 
    def __init__(self, *args, **kwargs): 
     self._running = False 
     self._relx = None 

     tk.Tk.__init__(self, *args, **kwargs) 

     self.pack_propagate(False) 
     self.configure(width=400, height=400) 
     self.label = tk.Label(self, text="hello, world", background="red") 
     self.button = tk.Button(self, text="Start", command=self.toggle) 
     self.button.pack(side="top") 

    def toggle(self): 
     '''toggle animation on or off''' 
     self._running = not self._running 
     if self._running: 
      self.button.configure(text="Stop") 
      self.moveit() 
     else: 
      self.button.configure(text="Start") 

    def moveit(self): 
     '''Animate the label''' 
     if not self._running: 
      # animation has been stopped 
      # hide the label from view. 
      self.label.place_forget() 

     if self._running: 
      if not self.label.winfo_viewable(): 
       # not visible; establish future locations 
       self._relx = [.5, .4, .3, .2, .1, 0] 
      relx = self._relx.pop(0) 
      self._relx.append(relx) 
      self.label.place(relx=relx, rely=0.7) 
      self.after(1000, self.moveit) 

if __name__ == "__main__": 
    app = SampleApp() 
    app.mainloop() 
0

您必須發信號通知舊線程以某種方式退出。使用鎖執行可能是最容易的 - 創建新線程並獲取它時創建一個鎖。當線程不再需要時,您可以釋放它。線程只需要在主循環中檢查它的鎖是否仍然鎖定 - 如果不是,它將刪除標籤並退出。在這裏你的代碼的修改版本(替換「這裏刪除標籤」通過適當的代碼註釋):

import thread 
from Tkinter import * 
import random 
import time 
Admin=Tk() 
lock = None 
def moveit(number): 
    global lock 
    songas=Label(Admin,text=number,bg='red') 
    def ji(lock): 
     plad=0.0 
     recount=0 
     times=0 
     while 1: 
      plad-=0.1 
      recount+=1 
      times+=1 
      time.sleep(0.5) 
      pls=0.0 
      pls+=plad 


      if recount==4: 

       pls=0 
       plad=0.0 
       recount=0 

      songas.place(relx=pls,rely=0.7) 

      if not lock.locked(): 
       # Remove label here 
       break 

    if lock: 
     # Signal old thread to exit 
     lock.release() 
    lock = thread.allocate_lock() 
    lock.acquire() 
    thread.start_new_thread(ji,(lock,)) 

za=random.random() 

button=Button(Admin,text='Press',command=lambda:moveit(str(za))) 
button.place(relx=0.2) 
Admin.mainloop()