开发者

Get rid of a label inside a thread?

so i have this code:

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开发者_如何学Go.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()

And it starts to move to the left but if you press the 'press' button again it puts some more numbers on top of the old ones. does any one know how to erase the old numbers to make it so there are only the knew ones?


Tkinter isn't thread safe -- you can't manipulate widgets in any thread except the main one or you'll get undefined results.

You don't need threads for this. Your code adds an infinite loop, but the application already has an infinite loop (the event loop) that you can take advantage of.

If you want to move some item create a function that does two things. First, it does whatever it is you want, such as move the item. Second, it uses the standard after method to call itself again in a short amount of time (for example, half a second or 500ms). This way you let your event loop drive the animation, you don't need threads, and your UI stays responsive.

Here's an example. I doubt it does exactly what you want because I'm not certain of exactly what you want.

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()


You must signal the old thread to exit somehow. It is probably easiest to perform with locks - you create a lock when creating a new thread and acquire it. And you release it when the thread is no longer needed. The thread then only needs to check in the main loop whether its lock is still locked - if it isn't it will remove the label and exit. Here the modified version of your code (replace "Remove label here" comment by suitable code):

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()
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜