2011-06-28 159 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()