@solid477

Как исправить RuntimeWarning: coroutine was never awaited?

Доброго времени суток. Мне необходимо выполнять 10 раз цикл в методе woriking, делаю программу на PyQt и при нажатии на кнопку получаю ошибку:
RuntimeWarning: coroutine 'Ui_MainWindow.working' was never awaited
sys.exit(app.exec_())
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

from datetime import datetime
from PyQt5 import QtCore, QtGui, QtWidgets
import asyncio
import requests

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(493, 267)
        font = QtGui.QFont()
        font.setFamily("WhitehallCyr")
        font.setPointSize(12)
        MainWindow.setFont(font)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        MainWindow.setInputMethodHints(QtCore.Qt.ImhNone)
        MainWindow.setIconSize(QtCore.QSize(48, 48))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lblAPI = QtWidgets.QLabel(self.centralwidget)
        self.lblAPI.setGeometry(QtCore.QRect(20, 14, 91, 21))
        font = QtGui.QFont()
        font.setFamily("Copperplate Cyrillic")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        font.setStyleStrategy(QtGui.QFont.PreferDefault)


        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.pushButton.clicked.connect(self.working)

    async def working(self):
        for i in range(5):
            try:
                x = requests.get('https://w3schools.com')
                print(x.status_code)
                break
            except:
                self.lblResText_2.setText("Ошибка!")


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Строка 1"))
        self.lblAP.setText(_translate("MainWindow", "Строка 2: "))
        self.lblA.setText(_translate("MainWindow", "Строка 3: "))
        self.lblS.setText(_translate("MainWindow", "Строка 4: "))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Подскажите пожалуйста, как сделать асинхронное выполнение цикла в количестве 10 раз ?
  • Вопрос задан
  • 8470 просмотров
Пригласить эксперта
Ответы на вопрос 3
Просто так асинхронный код в синхронном работать не будет.
Плюс минус о чем и говорит ошибка, что задачу поставили, но никогда не запускали - примерный вольная трактовка
Что бы подружить надо использовать asyncqt
ну и в целом не плохо было бы основы по питону для начала подтянуть, прежде чем писать асинхронные программы

print, request - синхронные в вашем коде нуль смысла асихронности
перехватывать все исключения тоже не надо, может быть много побочек
Ответ написан
Vindicar
@Vindicar
RTFM!
self.pushButton.clicked.connect(self.working)
А ты уверен, что обработчиком нажатия кнопки может быть корутина (async-функция)?
По-моему, там должна быть обычная функция.
Ответ написан
Комментировать
@trankov
Проблем тут две.

Во-первых, недостаточно просто написать async, чтобы код начал выполняться асинхронно. Это всего лишь помечает, что данная функция это корутина для запуска в асинхронном контексте. Здесь нужен не цикл из 5 итераций, а 5 асинхронных функций, которые будут запущены через asyncio, и отработают не по очереди, а конкурентно.

Во-вторых (что вызывает сообщение об ошибке) — clicked.connect принимает в качестве аргумента Callable, а не Coroutine. Для того, чтобы вызвать асинхронную функцию, вызывающий код должен использовать await. В .connect никакого await не прописано. Соответственно, и ошибка возникает: was never awaited. То есть в качестве возвращаемого значения происходит попытка вернуть объявленную корутину вне асинхронного контекста.

Что тут можно сделать. Во-первых, использовать нативную для QT асинхронность. Во-вторых, сделать def working обычной функцией, которая вызывает цепочку связанных корутин через asyncio. Но это будет отдельный от QT цикл событий, то есть внутри себя он будет асинхронным, но QT-приложение до своего полного выполнения заблокирует всё равно.

Так что пользуйтесь асинхронным инструментарием, предлагаемым QT из коробки.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы