Избавиться от ярлыка внутри потока? - PullRequest
0 голосов
/ 28 июня 2011

поэтому у меня есть этот код:

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

И он начинает двигаться влево, но если вы снова нажмете кнопку «Нажать», он поместит еще несколько чисел поверх старых. Кто-нибудь знает, как стереть старые числа, чтобы сделать так, чтобы были только известные?

Ответы [ 2 ]

1 голос
/ 28 июня 2011

Tkinter не является потокобезопасным - вы не можете манипулировать виджетами ни в одном потоке, кроме основного, иначе вы получите неопределенные результаты.

Вам не нужны темы для этого. Ваш код добавляет бесконечный цикл, но в приложении уже есть бесконечный цикл (цикл обработки событий), которым вы можете воспользоваться.

Если вы хотите переместить какой-либо элемент, создайте функцию, которая делает две вещи. Во-первых, он делает все, что вы хотите, например, перемещает элемент. Во-вторых, он использует стандартный метод after для повторного вызова себя за короткое время (например, полсекунды или 500 мс). Таким образом, вы позволяете своему циклу событий управлять анимацией, вам не нужны потоки, и ваш пользовательский интерфейс остается отзывчивым.

Вот пример. Я сомневаюсь, что это именно то, что вы хотите, потому что я не уверен, что именно вы хотите.

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 голосов
/ 28 июня 2011

Вы должны дать сигнал старому потоку, чтобы как-то выйти.Вероятно, это проще всего сделать с блокировками - вы создаете блокировку при создании нового потока и получаете ее.И вы отпускаете его, когда поток больше не нужен.Затем поток должен только проверить в основном цикле, заблокирована ли его блокировка - если это не так, он удалит метку и выйдет.Вот измененная версия вашего кода (замените комментарий «Удалить метку здесь» подходящим кодом):

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...