Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
stop multiple threads
#1
Hello,
I work with python 3.7 and want to develop a litle animation allowing a dot to move thanks to recorded data.
i create 2 threads, one thread is used to "catch" new data (a simple incrementation but recorded from a tracking system later) and an other thread to run the dot move. I want to stop the 2 threads and the widget (fen) with an event (a button QUIT) but i don't succeed: any idea?
my code is below
Thanks!
# moving point (see p 366 example in python book)
from tkinter import *
import time,threading

x,y= 10,10# global variable

class threadCollectData(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.collect=1
	
    def run(self):
        global x,y # to modify x, y in a function
        while self.collect==1:
            x+=0.00001
            y=y
			
    def stop(self): # method to stop the thread
        self.collect=0
		
	
class threadMovingPoint(threading.Thread):
    def __init__(self,canevas,Mvt_pt):
        threading.Thread.__init__(self)
        self.can=canevas
        self.Mvt_pt=Mvt_pt #
        self.anim=1 #flag to launch animation
		
    def run(self):
        while self.anim==1:
            self.can.coords(self.Mvt_pt,x-5,y-5,x+5,y+5)
            time.sleep(1)
    def stop(self): 
        self.anim=0
			


    
fen=Tk()
fen.title('moving point')
can=Canvas(fen,width=400,height=250,bg="white")
can.pack(side=LEFT)
movingPoint=can.create_oval(10,10,20,20,fill='red')
t_C=threadCollectData()
t_M=threadMovingPoint(can,movingPoint)
Button(fen,text='Move',command=t_M.start).pack(side=BOTTOM)
#bou1=Button(fen,text='stop Thread 1', command=t_M.stop)
#bou1.pack(side=BOTTOM)
#bou2=Button(fen,text='stop Thread 2', command=t_C.stop)
#bou2.pack(side=BOTTOM)
t_C.start()
bou3=Button(fen,text='QUIT', command=???) # <-- how to close the threads t_M and t_C and fen?
bou3.pack(side=BOTTOM)


fen.mainloop() # Démarrage du gestionnaire d'évenements
fen.destroy()
	
		
Reply
#2
For the threadMovingPoint, I suggest to use a Condition object instead of time.sleep()
class threadMovingPoint(threading.Thread):
    def __init__(self,canevas,Mvt_pt):
        threading.Thread.__init__(self)
        self.can=canevas
        self.Mvt_pt=Mvt_pt #
        self.cond = threading.Condition()
        self.anim=1 #flag to launch animation
         
    def run(self):
        with self.cond:
            while self.anim:
                self.can.coords(self.Mvt_pt,x-5,y-5,x+5,y+5)
                self.cond.wait(timeout=1.0)

    def stop(self):
        with self.cond:
            self.anim=0
            self.cond.notify()
        self.join()
For the other thread, I'm not sure it is a good idea to have a loop running indefinitely without any pause. Don't you want to add some sleeping time in the loop? I suppose that in the future, if you have a tracking system, there will be some sort of blocking select() call. You could perhaps model this with another Condition instance for the time being.
Reply
#3
hello,
Thanks for your response, i think your advice will improve my code but my main problem is already here, how can i stop the two threads with one event (a quit button)?
thanks!
Reply
#4
(Nov-14-2018, 09:29 AM)jeuvrey Wrote: but my main problem is already here,
Doesn't my code sto the threadMovingPoint when you invoke the stop function? Or perhaps you need to write a command to invoke the stop functions?
Reply
#5
Here it is using multiprocessing if it helps. https://pymotw.com/3/multiprocessing/index.html
import sys
if 3 == sys.version_info[0]: ## 3.X is default if dual system
    import tkinter as tk     ## Python 3.x
else:
    import Tkinter as tk     ## Python 2.x

import time
from multiprocessing import Process

class TestClass():
    def test_f(self, spaces=1):
        ctr = spaces
        while True:
            ctr += 1
            print(" "*spaces, ctr)
            time.sleep(1.0)

    def tk_quit(self):
        root=tk.Tk()
        tk.Button(root, text="Quit", command=root.quit,
                  width=10).grid()
        root.mainloop()

if __name__ == '__main__':
     ## run functions in the background
     CT=TestClass()
     p = Process(target=CT.test_f)
     p.start()
     ## run same function in another process to 
     ## simulate 2 different processes
     p2 = Process(target=CT.test_f, args=(10,))
     p2.start()

     CT.tk_quit()
     print("terminate process")
     if p.is_alive():
         p.terminate()
         p.join()
     if p2.is_alive():
         p2.terminate()
         p2.join() 
Reply
#6
Thanks,
It is fun because i just think about using multiprocessing ten minutes ago.
Maybe this solution is more suited to my situation. I want to move a dot with data coming from a tracking system.
Maybe it will be useful for some people, here is my code using 2 threads and kill them with a STOP button.
from tkinter import *
import time,threading

x,y= 10,10# global variable 

def threadCollectData(e):
    global x,y # to modify x, y in a function
    while not e.isSet():  # while evt not set to 1
        x+=1
        y=y
        print('Th 1 run')
        time.sleep(0.01)

def threadMovingPoint(e,can,movingPoint):
    global x,y
    while not e.isSet():
        can.coords(movingPoint,x-5,y-5,x+5,y+5)
        print('Th 2 run')
        #time.sleep(0.1)
  

fen=Tk()
fen.title('moving point')
can=Canvas(fen,width=400,height=250,bg="white") 
can.pack(side=LEFT)
movingPoint=can.create_oval(10,10,20,20,fill='red')
evt=threading.Event() # Thread evenement creation
t1= threading.Thread(target=threadCollectData,args=(evt,)) # Thread 1 creation
t1.start()
t2= threading.Thread(target=threadMovingPoint,args=(evt,can,movingPoint)) # Thread 2 creation
Button(fen,text='Move',command=t2.start).pack(side=BOTTOM) # start the t1 thread
bou3=Button(fen,text='STOP', command=evt.set) # Evt set to 1 will stop the 2 threads
bou3.pack(side=BOTTOM)
fen.mainloop() # Start evement manager
Thanks!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  What to do to stop all these threads? Valjean 3 507 Oct-02-2023, 01:50 PM
Last Post: deanhystad
  Trying to separate a loop across multiple threads stylingpat 0 1,651 May-05-2021, 05:21 PM
Last Post: stylingpat
  Get average of multiple threads Contra_Boy 1 13,991 May-05-2020, 04:51 PM
Last Post: deanhystad
  Quitting multiple threads MuntyScruntfundle 3 2,616 Oct-17-2018, 05:14 AM
Last Post: volcano63
  How to run multiple threads properly cyberion1985 6 5,773 Dec-29-2017, 09:45 AM
Last Post: cyberion1985

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020