Jan-18-2019, 11:11 AM
Hello,
this topic has been ever discuted on differents forums but i don't ever understand how to associate tkinter and an asyncio task without freezing the tkinter animation.
I tried to put the asyncio task on a thread while using tkinter on the main thread.
i succeeded to display alternatively the word 'GUI' and 'async' (see my code) but when i try to move my circle with streamed data, the animation freeze (no move of my circle).here is my code:
this topic has been ever discuted on differents forums but i don't ever understand how to associate tkinter and an asyncio task without freezing the tkinter animation.
I tried to put the asyncio task on a thread while using tkinter on the main thread.
i succeeded to display alternatively the word 'GUI' and 'async' (see my code) but when i try to move my circle with streamed data, the animation freeze (no move of my circle).here is my code:
import asyncio import qtm import xml.etree.ElementTree as ET from queue import * from tkinter import * import time,threading # Queue used to send data from async thread to gui thread queue_async_to_gui=Queue() async def package_receiver(queue_async,label,dico_marker): while True: packet = await queue_async.get() if packet is None: break header, markers = packet.get_3d_markers() i=0 ''' Data are stored in a dictionnary''' for marker in markers: dico_marker[label[i%len(label)],'X',i]=marker.x i=i+1 if (i==1): # 'P1' print('async') queue_async_to_gui.put(marker.x) async def shutdown(delay, connection, task_data_reception, queue_async): # wait desired time before exiting await asyncio.sleep(delay) # make sure package_receiver task exits queue_async.put_nowait(None) await task_data_reception # tell qtm to stop streaming await connection.stream_frames_stop() # This function setup the connection with QTM to stream the data async def setup_connection(): connection = await qtm.connect("127.0.0.1",version="1.16") if connection is None: return xml_string=await connection.get_parameters(parameters=["3d"]) root = ET.fromstring(xml_string) label=[]# list creation dico_marker={} # dictionnary creation for sub1 in root: for name in sub1.iter('Name'): label.append(name.text) queue_async = asyncio.Queue() task_data_reception=asyncio.create_task(package_receiver(queue_async,label,dico_marker)) await connection.stream_frames(components=["3d"], on_packet=queue_async.put_nowait) asyncio.create_task(shutdown(10, connection, task_data_reception, queue_async)) def move_pt(can,movingPoint,t): while t<15: x=queue_async_to_gui.get_nowait() x=x/(-10) y=10 can.coords(movingPoint,x-5,y-5,x+5,y+5) time.sleep(0.05) t+=0.05 print('GUI') # main thread -> GUI animation def GUI_pt(): 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') Button(fen,text='start',command=lambda:move_pt(can,movingPoint,0)).pack(side=BOTTOM) # start the animation fen.mainloop() def start_receive(): asyncio.set_event_loop(asyncio.new_event_loop())# create event loop in the new thread asyncio.ensure_future(setup_connection()) # creation of future object that will eventually give a result some time in the future loop=asyncio.get_event_loop() # get the event loop which schedule my coroutine loop.run_forever() #asyncio.run(setup_connection()) th=threading.Thread(target=start_receive) th.start() GUI_pt()Any idea? thanks!