Skip to content

Asynchronous listening and processing of multicast messages in PySide6 app #170

Description

@Antoine101

Hi all,

I am having difficulties integrating asyncio with Pyside for the following use case.
I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

What I want to acheive:

I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

In this proxy example:

I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
enter image description here

I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

Anyway, I have tried the following qt doc minimal example but it does not work.

And now I am calling for your help.

Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

EMITTER.py

import socket
import time
import struct
import random
def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
try:
while True:
# Generate a random value for port1
value1 = random.randint(1, 100)
message1 = f"{value1}"
sock.sendto(message1.encode(), (multicast_group, port1))
print(f"Sent to port {port1}: {message1}")
# Generate a random value for port2
value2 = random.randint(1, 100)
message2 = f"{value2}"
sock.sendto(message2.encode(), (multicast_group, port2))
print(f"Sent to port {port2}: {message2}")
time.sleep(1)
except KeyboardInterrupt:
print("\nExiting the program.")
finally:
sock.close()
if __name__ == "__main__":
port1 = 5000
port2 = 6000
send_multicast_messages(port1, port2)

APP.py

import sys
from PySide6.QtWidgets import (
QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Port Monitor")
self.setGeometry(100, 100, 400, 300)
# Create widgets
self.label1 = QLabel("Port 5000:")
self.text_edit1 = QTextEdit()
self.text_edit1.setReadOnly(True)
self.label2 = QLabel("Port 6000:")
self.text_edit2 = QTextEdit()
self.text_edit2.setReadOnly(True)
# Layout
layout = QVBoxLayout()
layout.addWidget(self.label1)
layout.addWidget(self.text_edit1)
layout.addWidget(self.label2)
layout.addWidget(self.text_edit2)
# Central widget
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

Thank you very much in advance for your help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
     blocks
    (function() {
    function addCopyButtons() {
    document.querySelectorAll('pre code').forEach(function(codeBlock) {
    if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
    codeBlock.parentElement.setAttribute('data-copy-added', 'true');
    var btn = document.createElement('button');
    btn.textContent = 'Copy';
    btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
    btn.onmouseover = function() { this.style.opacity = '1'; };
    btn.onmouseout = function() { this.style.opacity = '0.7'; };
    btn.onclick = function() {
    navigator.clipboard.writeText(codeBlock.textContent).then(function() {
    btn.textContent = 'Copied!';
    setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
    });
    };
    codeBlock.parentElement.style.position = 'relative';
    codeBlock.parentElement.appendChild(btn);
    });
    }
    addCopyButtons();
    // Re-run on dynamic content
    var observer = new MutationObserver(addCopyButtons);
    observer.observe(document.body, { childList: true, subtree: true });
    })();
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
    Skip to content

    Asynchronous listening and processing of multicast messages in PySide6 app #170

    Description

    @Antoine101

    Hi all,

    I am having difficulties integrating asyncio with Pyside for the following use case.
    I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
    I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

    What I want to acheive:

    I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
    I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
    Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

    In this proxy example:

    I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
    On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
    enter image description here

    I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

    Anyway, I have tried the following qt doc minimal example but it does not work.

    And now I am calling for your help.

    Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

    EMITTER.py

    import socket
    import time
    import struct
    import random
    def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    ttl = struct.pack('b', 1)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
    try:
    while True:
    # Generate a random value for port1
    value1 = random.randint(1, 100)
    message1 = f"{value1}"
    sock.sendto(message1.encode(), (multicast_group, port1))
    print(f"Sent to port {port1}: {message1}")
    # Generate a random value for port2
    value2 = random.randint(1, 100)
    message2 = f"{value2}"
    sock.sendto(message2.encode(), (multicast_group, port2))
    print(f"Sent to port {port2}: {message2}")
    time.sleep(1)
    except KeyboardInterrupt:
    print("\nExiting the program.")
    finally:
    sock.close()
    if __name__ == "__main__":
    port1 = 5000
    port2 = 6000
    send_multicast_messages(port1, port2)
    

    APP.py

    import sys
    from PySide6.QtWidgets import (
    QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
    )
    class MainWindow(QMainWindow):
    def __init__(self):
    super().__init__()
    self.setWindowTitle("Port Monitor")
    self.setGeometry(100, 100, 400, 300)
    # Create widgets
    self.label1 = QLabel("Port 5000:")
    self.text_edit1 = QTextEdit()
    self.text_edit1.setReadOnly(True)
    self.label2 = QLabel("Port 6000:")
    self.text_edit2 = QTextEdit()
    self.text_edit2.setReadOnly(True)
    # Layout
    layout = QVBoxLayout()
    layout.addWidget(self.label1)
    layout.addWidget(self.text_edit1)
    layout.addWidget(self.label2)
    layout.addWidget(self.text_edit2)
    # Central widget
    container = QWidget()
    container.setLayout(layout)
    self.setCentralWidget(container)
    if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())
    

    Thank you very much in advance for your help.

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      No labels
      No labels

      Type

      No type

      Projects

      No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
      Skip to content

      Asynchronous listening and processing of multicast messages in PySide6 app #170

      Description

      @Antoine101

      Hi all,

      I am having difficulties integrating asyncio with Pyside for the following use case.
      I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
      I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

      What I want to acheive:

      I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
      I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
      Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

      In this proxy example:

      I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
      On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
      enter image description here

      I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

      Anyway, I have tried the following qt doc minimal example but it does not work.

      And now I am calling for your help.

      Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

      EMITTER.py

      import socket
      import time
      import struct
      import random
      def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
      sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
      ttl = struct.pack('b', 1)
      sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
      try:
      while True:
      # Generate a random value for port1
      value1 = random.randint(1, 100)
      message1 = f"{value1}"
      sock.sendto(message1.encode(), (multicast_group, port1))
      print(f"Sent to port {port1}: {message1}")
      # Generate a random value for port2
      value2 = random.randint(1, 100)
      message2 = f"{value2}"
      sock.sendto(message2.encode(), (multicast_group, port2))
      print(f"Sent to port {port2}: {message2}")
      time.sleep(1)
      except KeyboardInterrupt:
      print("\nExiting the program.")
      finally:
      sock.close()
      if __name__ == "__main__":
      port1 = 5000
      port2 = 6000
      send_multicast_messages(port1, port2)
      

      APP.py

      import sys
      from PySide6.QtWidgets import (
      QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
      )
      class MainWindow(QMainWindow):
      def __init__(self):
      super().__init__()
      self.setWindowTitle("Port Monitor")
      self.setGeometry(100, 100, 400, 300)
      # Create widgets
      self.label1 = QLabel("Port 5000:")
      self.text_edit1 = QTextEdit()
      self.text_edit1.setReadOnly(True)
      self.label2 = QLabel("Port 6000:")
      self.text_edit2 = QTextEdit()
      self.text_edit2.setReadOnly(True)
      # Layout
      layout = QVBoxLayout()
      layout.addWidget(self.label1)
      layout.addWidget(self.text_edit1)
      layout.addWidget(self.label2)
      layout.addWidget(self.text_edit2)
      # Central widget
      container = QWidget()
      container.setLayout(layout)
      self.setCentralWidget(container)
      if __name__ == "__main__":
      app = QApplication(sys.argv)
      window = MainWindow()
      window.show()
      sys.exit(app.exec())
      

      Thank you very much in advance for your help.

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Type

        No type

        Projects

        No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
        Skip to content

        Asynchronous listening and processing of multicast messages in PySide6 app #170

        Description

        @Antoine101

        Hi all,

        I am having difficulties integrating asyncio with Pyside for the following use case.
        I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
        I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

        What I want to acheive:

        I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
        I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
        Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

        In this proxy example:

        I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
        On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
        enter image description here

        I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

        Anyway, I have tried the following qt doc minimal example but it does not work.

        And now I am calling for your help.

        Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

        EMITTER.py

        import socket
        import time
        import struct
        import random
        def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        ttl = struct.pack('b', 1)
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
        try:
        while True:
        # Generate a random value for port1
        value1 = random.randint(1, 100)
        message1 = f"{value1}"
        sock.sendto(message1.encode(), (multicast_group, port1))
        print(f"Sent to port {port1}: {message1}")
        # Generate a random value for port2
        value2 = random.randint(1, 100)
        message2 = f"{value2}"
        sock.sendto(message2.encode(), (multicast_group, port2))
        print(f"Sent to port {port2}: {message2}")
        time.sleep(1)
        except KeyboardInterrupt:
        print("\nExiting the program.")
        finally:
        sock.close()
        if __name__ == "__main__":
        port1 = 5000
        port2 = 6000
        send_multicast_messages(port1, port2)
        

        APP.py

        import sys
        from PySide6.QtWidgets import (
        QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
        )
        class MainWindow(QMainWindow):
        def __init__(self):
        super().__init__()
        self.setWindowTitle("Port Monitor")
        self.setGeometry(100, 100, 400, 300)
        # Create widgets
        self.label1 = QLabel("Port 5000:")
        self.text_edit1 = QTextEdit()
        self.text_edit1.setReadOnly(True)
        self.label2 = QLabel("Port 6000:")
        self.text_edit2 = QTextEdit()
        self.text_edit2.setReadOnly(True)
        # Layout
        layout = QVBoxLayout()
        layout.addWidget(self.label1)
        layout.addWidget(self.text_edit1)
        layout.addWidget(self.label2)
        layout.addWidget(self.text_edit2)
        # Central widget
        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)
        if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec())
        

        Thank you very much in advance for your help.

        Metadata

        Metadata

        Assignees

        No one assigned

          Labels

          No labels
          No labels

          Type

          No type

          Projects

          No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
          Skip to content

          Asynchronous listening and processing of multicast messages in PySide6 app #170

          Description

          @Antoine101

          Hi all,

          I am having difficulties integrating asyncio with Pyside for the following use case.
          I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
          I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

          What I want to acheive:

          I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
          I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
          Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

          In this proxy example:

          I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
          On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
          enter image description here

          I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

          Anyway, I have tried the following qt doc minimal example but it does not work.

          And now I am calling for your help.

          Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

          EMITTER.py

          import socket
          import time
          import struct
          import random
          def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
          sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
          ttl = struct.pack('b', 1)
          sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
          try:
          while True:
          # Generate a random value for port1
          value1 = random.randint(1, 100)
          message1 = f"{value1}"
          sock.sendto(message1.encode(), (multicast_group, port1))
          print(f"Sent to port {port1}: {message1}")
          # Generate a random value for port2
          value2 = random.randint(1, 100)
          message2 = f"{value2}"
          sock.sendto(message2.encode(), (multicast_group, port2))
          print(f"Sent to port {port2}: {message2}")
          time.sleep(1)
          except KeyboardInterrupt:
          print("\nExiting the program.")
          finally:
          sock.close()
          if __name__ == "__main__":
          port1 = 5000
          port2 = 6000
          send_multicast_messages(port1, port2)
          

          APP.py

          import sys
          from PySide6.QtWidgets import (
          QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
          )
          class MainWindow(QMainWindow):
          def __init__(self):
          super().__init__()
          self.setWindowTitle("Port Monitor")
          self.setGeometry(100, 100, 400, 300)
          # Create widgets
          self.label1 = QLabel("Port 5000:")
          self.text_edit1 = QTextEdit()
          self.text_edit1.setReadOnly(True)
          self.label2 = QLabel("Port 6000:")
          self.text_edit2 = QTextEdit()
          self.text_edit2.setReadOnly(True)
          # Layout
          layout = QVBoxLayout()
          layout.addWidget(self.label1)
          layout.addWidget(self.text_edit1)
          layout.addWidget(self.label2)
          layout.addWidget(self.text_edit2)
          # Central widget
          container = QWidget()
          container.setLayout(layout)
          self.setCentralWidget(container)
          if __name__ == "__main__":
          app = QApplication(sys.argv)
          window = MainWindow()
          window.show()
          sys.exit(app.exec())
          

          Thank you very much in advance for your help.

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Type

            No type

            Projects

            No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
            Skip to content

            Asynchronous listening and processing of multicast messages in PySide6 app #170

            Description

            @Antoine101

            Hi all,

            I am having difficulties integrating asyncio with Pyside for the following use case.
            I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
            I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

            What I want to acheive:

            I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
            I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
            Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

            In this proxy example:

            I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
            On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
            enter image description here

            I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

            Anyway, I have tried the following qt doc minimal example but it does not work.

            And now I am calling for your help.

            Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

            EMITTER.py

            import socket
            import time
            import struct
            import random
            def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            ttl = struct.pack('b', 1)
            sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
            try:
            while True:
            # Generate a random value for port1
            value1 = random.randint(1, 100)
            message1 = f"{value1}"
            sock.sendto(message1.encode(), (multicast_group, port1))
            print(f"Sent to port {port1}: {message1}")
            # Generate a random value for port2
            value2 = random.randint(1, 100)
            message2 = f"{value2}"
            sock.sendto(message2.encode(), (multicast_group, port2))
            print(f"Sent to port {port2}: {message2}")
            time.sleep(1)
            except KeyboardInterrupt:
            print("\nExiting the program.")
            finally:
            sock.close()
            if __name__ == "__main__":
            port1 = 5000
            port2 = 6000
            send_multicast_messages(port1, port2)
            

            APP.py

            import sys
            from PySide6.QtWidgets import (
            QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
            )
            class MainWindow(QMainWindow):
            def __init__(self):
            super().__init__()
            self.setWindowTitle("Port Monitor")
            self.setGeometry(100, 100, 400, 300)
            # Create widgets
            self.label1 = QLabel("Port 5000:")
            self.text_edit1 = QTextEdit()
            self.text_edit1.setReadOnly(True)
            self.label2 = QLabel("Port 6000:")
            self.text_edit2 = QTextEdit()
            self.text_edit2.setReadOnly(True)
            # Layout
            layout = QVBoxLayout()
            layout.addWidget(self.label1)
            layout.addWidget(self.text_edit1)
            layout.addWidget(self.label2)
            layout.addWidget(self.text_edit2)
            # Central widget
            container = QWidget()
            container.setLayout(layout)
            self.setCentralWidget(container)
            if __name__ == "__main__":
            app = QApplication(sys.argv)
            window = MainWindow()
            window.show()
            sys.exit(app.exec())
            

            Thank you very much in advance for your help.

            Metadata

            Metadata

            Assignees

            No one assigned

              Labels

              No labels
              No labels

              Type

              No type

              Projects

              No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Asynchronous listening and processing of multicast messages in PySide6 app · Issue #170 · CabbageDevelopment/qasync · GitHub
              Skip to content

              Asynchronous listening and processing of multicast messages in PySide6 app #170

              Description

              @Antoine101

              Hi all,

              I am having difficulties integrating asyncio with Pyside for the following use case.
              I have read through numerous docs and articles but still struggle to assemble the pieces of the puzzle.
              I figured I should ask here directly. Sorry in advance if is not the appropriate channel. I didn't see any Discussions channel.

              What I want to acheive:

              I have several emitters (up to 30) sending messages independently every few milliseconds (200ms) in multicast.
              I have a python PySide app that needs to listen to these incoming messages, process them, and update a map plot accordingly (move shapes, change colors of markers, etc...).
              Because I cannot share what I am working on for confidentialy purposes, I have devised a proxy example that is simpler and close enough to my actual need that I can share here.

              In this proxy example:

              I have an emitter script that sends messages indefinitely on two ports, at a rate that can be modified (here the sleep time is of 1s). This simulates my sensors that emit messages. In this script, messages are sent each time one after the other. To be close to reality I guess we ought to have two separate scripts run in two different consoles. But I think this one can do the trick here. The messages consist in random numbers in this example.
              On the receiving side, I want to create an app with PySide that receives those messages, processes them (multiply the numbers by 100) and displays them in two text boxes, each associated with a different port.
              enter image description here

              I am looking at using an asynchronous approach with asyncio here because I think my problem is mainly I/O-bound. The processing stage is minimal. In my real example it would amount to updating shapes on a satellite view map (leaflet via javascript), maybe doing a few calculations on the received data before that, but nothing too CPU-intensive. I also chose to embed my plot in a PySide app to be able to add more buttons and features later on. Please feel free to indicate any other solution that would be more suitable (multiple threads? multiple processes?).

              Anyway, I have tried the following qt doc minimal example but it does not work.

              And now I am calling for your help.

              Below are the emitter script as well as the code base for the PySide app, without the asynchronous listening and processing stages (I asked Le Chat to generate the full Pyside app but it never works that's why I am giving you only the base code to fill in here):

              EMITTER.py

              import socket
              import time
              import struct
              import random
              def send_multicast_messages(port1, port2, multicast_group='224.1.1.1'):
              sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
              sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
              ttl = struct.pack('b', 1)
              sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
              try:
              while True:
              # Generate a random value for port1
              value1 = random.randint(1, 100)
              message1 = f"{value1}"
              sock.sendto(message1.encode(), (multicast_group, port1))
              print(f"Sent to port {port1}: {message1}")
              # Generate a random value for port2
              value2 = random.randint(1, 100)
              message2 = f"{value2}"
              sock.sendto(message2.encode(), (multicast_group, port2))
              print(f"Sent to port {port2}: {message2}")
              time.sleep(1)
              except KeyboardInterrupt:
              print("\nExiting the program.")
              finally:
              sock.close()
              if __name__ == "__main__":
              port1 = 5000
              port2 = 6000
              send_multicast_messages(port1, port2)
              

              APP.py

              import sys
              from PySide6.QtWidgets import (
              QApplication, QMainWindow, QVBoxLayout, QTextEdit, QLabel, QWidget
              )
              class MainWindow(QMainWindow):
              def __init__(self):
              super().__init__()
              self.setWindowTitle("Port Monitor")
              self.setGeometry(100, 100, 400, 300)
              # Create widgets
              self.label1 = QLabel("Port 5000:")
              self.text_edit1 = QTextEdit()
              self.text_edit1.setReadOnly(True)
              self.label2 = QLabel("Port 6000:")
              self.text_edit2 = QTextEdit()
              self.text_edit2.setReadOnly(True)
              # Layout
              layout = QVBoxLayout()
              layout.addWidget(self.label1)
              layout.addWidget(self.text_edit1)
              layout.addWidget(self.label2)
              layout.addWidget(self.text_edit2)
              # Central widget
              container = QWidget()
              container.setLayout(layout)
              self.setCentralWidget(container)
              if __name__ == "__main__":
              app = QApplication(sys.argv)
              window = MainWindow()
              window.show()
              sys.exit(app.exec())
              

              Thank you very much in advance for your help.

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Type

                No type

                Projects

                No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions