所以我有这段代码:
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()
它开始向左移动,但是如果你再次按下“按下”按钮,它会在旧的按钮上面放置更多的数字。 有没有人知道如何删除旧数字,以便只有知道的数字?
答案 0 :(得分: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()
答案 1 :(得分: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()