@TonyTrueTony

Почему asyncio фризит pyqt5?

Есть два окна интерфейса, первое показывается при старте скрипта, второе после нажатия кнопки. Но так же, после нажатия кнопки создается asyncio соединение, принимающие сигналы.
Проблема в том, что как только устанавливается соединение весь интерфейс pyqt5 зависает. В чем ошибка и как это исправить?
Основная программа
import sys
from PyQt5 import QtWidgets, QtGui, QtWidgets
import loginform2, mainclient2
import tclient2


class ClientWindow(QtWidgets.QMainWindow, mainclient2.Ui_MainWindow):
    def __init__(self):
        super(ClientWindow, self).__init__()
        self.setupUi(self)
        self.setupWidget = QtWidgets.QWidget(self)
        self.config = loginform2.Ui_Form()
        self.config.setupUi(self.setupWidget)
        self.show()
        
        self.centralwidget.setHidden(True)
        self.config.pushButton.clicked.connect(self.start)
    
    def start(self):
        self.setupWidget.setHidden(True)
        self.centralwidget.setVisible(True)

        self.asynccode()


    def asynccode(self):

        import asyncio
        asyncio.run(tclient2.main('127.0.0.1', 8888))

        
if __name__ == '__main__':
    app = QtWidgets.QApplication([])
    main_window = ClientWindow()
    sys.exit(app.exec())

Код клиента
import asyncio


class aclient():
    def __init__(self, host, port):
        self.host = host
        self.port = port


    async def tcp_echo_client(self):
        reader, writer = await asyncio.open_connection(self.host, self.port)
        name = 'anonymous'
        writer.write(name.encode())
        while True:
            await self.test(reader)


    async def test(self, reader):
        incoming_message = await reader.read(1024)
        print('incoming message', incoming_message.decode())


async def main(host, port):
    await aclient(host, port).tcp_echo_client()
  • Вопрос задан
  • 2856 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
События графического интерфейса обрабатываются бесконечным циклом, который запускается, когда вы вызываете app.exec() Его нельзя останавливать, иначе приложение зависнет. Но eventloop - это тоже бесконечный цикл, который запускается, когда вы вызываете asyncio.run(). В результате цикл событий asyncio останавливает цикл событий Qt. Выхода может быть два: либо с помощью Quamash использовать один цикл и для asyncio и для Qt, либо запускать цикл asyncio в отдельном потоке (лучше QThread).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
laviol
@laviol
Кодер-разнорабочий
Рискну предположить, что происходит это из-за того, что asyncio.run() запускается не в отдельном потоке и перехватывает интерпретатор, пока asyncio event loop не завершит свою работу (спойлер: он не завершит).
Возможно, вот этот тред поможет решить проблему:
https://stackoverflow.com/questions/26270681/can-a...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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