如何创建控制和显示python - osc服务器数据的python GUI应用程序?



我是python初学者。我想创建一个Python GUI应用程序来控制OSC服务器(启动和停止)并将数据显示到窗口中。问题是,当我运行OSC服务器时,窗口没有出现,直到PSC服务器完成自己。而应该改变全局变量内数据的函数没有改变。

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

我正在寻找类似的问题,但我找不到解决方案。

使用threading。首先,我们启动一个单线程tkinter,并从它启动一个线程来与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()

我从这里取了程序的基。