Dup Ver Goto 📝

OscDebugConsole

PT2/lang/python/qt/pyside6/examples does not exist
To
93 lines, 307 words, 2933 chars Page 'OscDebugConsole' does not exist.

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