@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 раз ?
  • Вопрос задан
  • 9684 просмотра
Пригласить эксперта
Ответы на вопрос 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 из коробки.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы