I'm currently working on a Python application using PySide6 for the GUI. I have a QPushButton
and I want to connect its clicked
signal to an asynchronous function, but I'm running into some issues.
Here's a simplified version of my code:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Async Function Example")
self.login_button = QPushButton("Login", self)
self.login_button.clicked.connect(self.login_button_clicked)
async def login_button_clicked(self):
# Perform async tasks
print("test async button clicked!")
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
However, when I run this code, I receive the following error:
RuntimeWarning: coroutine 'MainWindow.login_button_clicked' was never awaited
app.exec()
I understand that the error is caused by not awaiting the asynchronous function. I have tried using the await keyword before the method call when connecting the signal, but PySide6 doesn't directly support connecting asynchronous functions to signals.
I've also attempted to work around this by using a helper function or a coroutine runner, but without success.
Could someone please guide me on how to properly connect an asynchronous function to a PySide6 button signal? Is there a recommended approach or workaround for this situation? Any code examples or suggestions would be greatly appreciated.
Thank you in advance for your help!
I ran into the same issue and I have created a package to solve it. The asyncio need to be setup properly to be able to work with PySide6.
Your code can be changed to:
pip install AsyncioPySide6
import sys
from AsyncioPySide6 import AsyncioPySide6
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Async Function Example")
self.login_button = QPushButton("Login", self)
self.login_button.clicked.connect(self.login_button_clicked)
def login_button_clicked(self):
async def asyncTask():
# Async wait for 4 seconds
await asyncio.timeout(4)
# Perform async tasks
print("test async button clicked!")
self.login_button.setEnabled(False)
AsyncioPySide6.runTask(asyncTask())
app = QApplication(sys.argv)
with AsyncioPySide6.use_asyncio():
main_window = MainWindow()
main_window.show()
app.exec()
Basically, you can execute any asynchronous task by using AsyncioPySide6.runTask. You can even manipulate GUI components within async tasks without using QMetaObject.invoke.