Python Forum
tkinter and asyncio
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
tkinter and asyncio
#1
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:
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!
Reply


Forum Jump:

User Panel Messages

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