Asynchrones Abhören und Verarbeiten in einer Pyside-AppPython

Python-Programme
Anonymous
 Asynchrones Abhören und Verarbeiten in einer Pyside-App

Post by Anonymous »

Ich habe Schwierigkeiten, Asyncio mit Pyside zu integrieren.
Was ich erreichen möchte:
  • Ich habe mehrere Emitter (bis zu 30), die alle paar Millisekunden (200 ms) unabhängig voneinander Nachrichten im Multicast senden.
  • Ich habe eine Python-PySide-App, die diese eingehenden Nachrichten abhören, verarbeiten und einen Kartenplot entsprechend aktualisieren muss (Formen verschieben, Farben von Markierungen ändern usw.).
Da ich aus Vertraulichkeitsgründen nicht mitteilen kann, woran ich arbeite, habe ich ein Proxy-Beispiel entwickelt, das einfacher und meinem tatsächlichen Bedarf nahe genug ist, das ich hier teilen kann.
In diesem Proxy-Beispiel:
  • Ich habe ein Emitter-Skript, das Nachrichten auf unbestimmte Zeit an zwei Ports sendet, und zwar mit einer Geschwindigkeit, die so hoch ist kann geändert werden (hier beträgt die Ruhezeit 1s). Dies simuliert meine Sensoren, die Nachrichten aussenden. In diesem Skript werden Nachrichten jeweils nacheinander gesendet. Um der Realität nahe zu kommen, sollten wir meiner Meinung nach zwei separate Skripte auf zwei verschiedenen Konsolen ausführen lassen. Aber ich denke, dieser hier kann den Zweck erfüllen. Die Nachrichten bestehen in diesem Beispiel aus Zufallszahlen.
  • Auf der Empfängerseite möchte ich mit PySide eine App erstellen, die diese Nachrichten empfängt, sie verarbeitet (die Zahlen mit 100 multiplizieren) und sie in zwei Textfeldern anzeigt, die jeweils einem anderen Port zugeordnet sind.
Image

Ich denke hier über die Verwendung eines asynchronen Ansatzes mit Asyncio nach, weil ich denke, dass mein Problem hauptsächlich E/A-gebunden ist. Der Verarbeitungsschritt ist minimal. In meinem realen Beispiel würde es darauf hinauslaufen, Formen auf einer Satellitenansichtskarte (Broschüre über Javascript) zu aktualisieren und vielleicht vorher ein paar Berechnungen mit den empfangenen Daten durchzuführen, aber nichts ist zu CPU-intensiv.
Ich habe mich auch dafür entschieden, meinen Plot in eine PySide-App einzubetten, um später weitere Schaltflächen und Funktionen hinzufügen zu können.
Bitte geben Sie uns gerne eine andere Lösung an, die besser geeignet wäre (mehrere Threads? mehrere Prozesse?).
Wie auch immer, ich habe es versucht Das folgende QT-Doc-Minimalbeispiel, aber es funktioniert nicht.
Und jetzt rufe ich Sie um Hilfe.
Unten finden Sie das Emitter-Skript sowie die Codebasis für die PySide-App, ohne die asynchronen Überwachungs- und Verarbeitungsphasen (ich habe Le Chat gebeten, die vollständige Pyside-App zu generieren, aber es funktioniert nie, deshalb gebe ich Ihnen hier nur den Basiscode zum Ausfüllen):
EMITTER.py

Code: Select all

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

Code: Select all

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())
Vielen Dank im Voraus für Ihre Hilfe.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post