This is a simple text window to which we can send OSC messages of the form
/append "Some text"
/set "Some more text"
/clear
and these appear in the window. It provides an easy way to print debug output to a window on a
remote machine. The ReceiverBase class handles creating a UDP socket and decoding OSC messages
(using python-osc) and hands off parsed messages to receiver.process_message(). It is better
to keep the receiver out of the debug window class, as this gives better flexibility and less coupling.
The debug window's only responsibility is showing what it is told to show; the Receiver's only
responsibility is to receive UDP packets, decode the OSC, and act on the messages, by calling
methods on the debug window.
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtNetwork import *
import sys
app = QApplication([])
class DebugWindow(QTextEdit):
def __init__(self,*xs,**kw):
super().__init__(*xs,**kw)
self.content = ""
self.updateContent()
self.font = QFont("Hack Nerd Font Mono",20)
self.setFont(self.font)
def updateContent(self):
self.setPlainText(self.content)
self.update()
def setContent(self,content):
self.content = content
self.updateContent()
def appendContent(self,newContent):
if len(self.content) > 0 and self.content[-1] != "\n":
self.content += "\n"
self.content += newContent
self.updateContent()
def keyPressEvent(self,e):
k = e.key()
if k == Qt.Key_Q:
return app.quit()
if k == Qt.Key_C:
return self.setContent("")
from pythonosc.osc_message import OscMessage
class ReceiverBase(QObject):
def __init__(self,target,port=4010):
self.target = target
self.udpSocket = QUdpSocket()
self.udpSocket.readyRead.connect(self.handleUdp)
self.udpSocket.bind(QHostAddress.Any,port)
def handleUdp(self):
while self.udpSocket.hasPendingDatagrams():
datagram = self.udpSocket.receiveDatagram(4096)
data = datagram.data().data()
print(f"Recv {data=} {len(data)} bytes")
try:
message = OscMessage(data)
except Exception as e:
print(f"Failed to parse {e} : {data=}")
return
self.processMessage(message)
def processMessage(self,message):
pass
class DebugWindowReceiver(ReceiverBase):
def processMessage(self,message):
addr = message.address
params = message.params
if addr == "append":
t = " ".join(map(str,params))
self.target.appendContent(t)
elif addr == "set":
t = " ".join(map(str,params))
self.target.setContent(t)
elif addr == "clear":
self.target.setContent("")
else:
print(f"Unrecognised {addr=}")
debugWindow = DebugWindow()
debugWindow.resize(900,600)
debugWindow.setContent("Mr Flibble\nHex Vision")
debugWindow.show()
receiver = DebugWindowReceiver(debugWindow,4009)
exit(app.exec())