PySide6 (and PyQt) not support asyncio by default but there are libraries like qasync that allow integrating eventloops. The following example is a simple sample of how to use asyncio.create_subprocess_exec()
with PySide6
import sys
import asyncio
from PySide6.QtCore import QObject, Signal
from PySide6.QtWidgets import QApplication, QTextEdit, QPushButton, QVBoxLayout, QWidget
import qasync
if sys.platform == "win32":
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
class ManagerProcess(QObject):
data_stdout_changed = Signal(bytes)
data_stderr_changed = Signal(bytes)
error_ocurred = Signal(Exception)
started = Signal()
finished = Signal()
def start(self, cmd):
asyncio.ensure_future(self._start(cmd))
async def _start(self, cmd):
try:
process = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
)
self.started.emit()
await asyncio.wait(
[
asyncio.create_task(
self._read_stream(process.stdout, self.data_stdout_changed)
),
asyncio.create_task(
self._read_stream(process.stderr, self.data_stderr_changed)
),
]
)
rc = await process.wait()
self.finished.emit()
except OSError as e:
self.error_ocurred.emit(e)
async def _read_stream(self, stream, signal):
while True:
line = await stream.readline()
if line:
signal.emit(line)
else:
break
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.text_edit = QTextEdit(readOnly=True)
button = QPushButton("Start")
lay = QVBoxLayout(self)
lay.addWidget(button)
lay.addWidget(self.text_edit)
self.manager = ManagerProcess()
button.clicked.connect(self.handle_clicked)
self.manager.data_stdout_changed.connect(self.handle_stdout)
self.manager.data_stderr_changed.connect(self.handle_stderr)
def handle_clicked(self):
cmd = ["ping", "8.8.8.8"]
self.manager.start(cmd)
def handle_stdout(self, data):
self.text_edit.append(f"[STDOUT]: {data}")
def handle_stderr(self, data):
self.text_edit.append(f"[STDERR]: {data}")
def main():
app = QApplication(sys.argv)
loop = qasync.QEventLoop(app)
asyncio.set_event_loop(loop)
w = Widget()
w.show()
with loop:
loop.run_forever()
if __name__ == "__main__":
main()