I am beginner in python. I want to create Python GUI application that control OSC Server (start and stop) and displaying the data into window. The problem is, when I run OSC Server the window did't show up until PSC Server finishes itself. And the function that supposed to change the data within global variable failed to changed.
import tkinter as tk
from tkinter import ttk
from pythonosc.osc_server import AsyncIOOSCUDPServer
from pythonosc.dispatcher import Dispatcher
import asyncio
ip = "0.0.0.0"
port = 5000
koneksi=None
def filter_handler(address, *args):
# print(f"{address}: {args}")
for arg in args:
status(arg)
def status(stat):
global koneksi
if stat==1:
koneksi="Connected"
else:
koneksi="Disconnected"
# print(koneksi)
dispatcher = Dispatcher()
dispatcher.map("/muse/elements/touching_forehead", filter_handler)
async def loop():
"""Example main loop that only runs for 10 iterations before finishing"""
for i in range(2):
print(f"Loop {i}")
await asyncio.sleep(1)
async def init_main():
server = AsyncIOOSCUDPServer((ip, port), dispatcher, asyncio.get_event_loop())
transport, protocol = await server.create_serve_endpoint() # Create datagram endpoint and start serving
await loop() # Enter main loop of program
transport.close() # Clean up serve endpoint
def tombol_click():
asyncio.run(init_main())
window=tk.Tk()
window.geometry("600x400")
window.resizable(False,False)
frame=ttk.Frame(window)
labelDevice=ttk.Label(frame,text="Device :")
labelDevice.grid(row=0,column=0, padx=10,pady=10)
labelStatus=ttk.Label(frame,text=koneksi)
labelStatus.grid(row=0,column=1, padx=10,pady=10)
tombol_sapa = ttk.Button(frame,text="start",command=tombol_click())
tombol_sapa.grid(row=1,column=0,padx=10, pady=10)
frame.pack()
window.mainloop()
I'm trying to search similar problem but I can't find the solution.
Using threading
. First, we launch a single-threaded tkinter
and from it we launch a thread to work with the OSC server
.
import time
import threading
import tkinter as tk
# Create a window with a button and a label.
class App(tk.Tk):
def __init__(self):
super().__init__()
self.button = tk.Button(self, command=self.start_action, text="start")
self.button.pack(padx=100, pady=50)
self.lable = tk.Label(self, text="initial value")
self.lable.pack(padx=100, pady=50)
# We start an additional thread for the PSC Server.
def start_action(self):
self.button.config(state=tk.DISABLED)
thread = threading.Thread(target=self.init_main)
thread.start()
self.check_thread(thread)
# We make the button active only after the flow is completed.
def check_thread(self, thread):
if thread.is_alive():
self.check = self.after(500, lambda: self.check_thread(thread))
else:
self.button.config(state=tk.NORMAL)
def init_main(self):
# start dispatcher,server
self.loop() # Enter main loop of program
# Clean up serve endpoint
def loop(self):
"""Example main loop that only runs for 10 iterations before finishing"""
for i in range(2):
print(f"Loop {i}")
self.lable.config(text=f"Loop {i}")
time.sleep(1)
if __name__ == "__main__":
app = App()
app.mainloop()
I took the basis for the program from here.