IBM Watson с окном pyqt5 зависает в цикле while - PullRequest
1 голос
/ 29 апреля 2020

Мое окно зависает в то время как l oop как я могу это исправить или как ждать ввода в l oop, если я добавляю ввод (""), что-то программа больше не зависает, но я не хочу использовать консоль.

from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

import sys
from PyQt5 import QtWidgets


class Pencere(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.gr=0
        self.say=0
        self.yazi_alani=QtWidgets.QLineEdit()
        self.send=QtWidgets.QPushButton("Send")

        self.cevap=QtWidgets.QLabel("")

        v_box=QtWidgets.QVBoxLayout()
        h_box=QtWidgets.QHBoxLayout()
        h_box.addStretch()
        v_box.addWidget(self.cevap)
        v_box.addStretch()
        v_box.addWidget(self.yazi_alani)
        v_box.addWidget(self.send)



        h_box.addLayout(v_box)
        self.setLayout(h_box)


        self.send.clicked.connect(self.gonder)



        self.setGeometry(200,200,500,500)
        self.show()
        self.watson()
    def watson(self):
        while self.say==0:
            self.say+=1
            # Set up Assistant service.
            authenticator = IAMAuthenticator('4CpKAKUsLRpYvcUX_nQRR1MGnYM1WqJLUhE4XS-p4B7Y') # replace with API key
            service = AssistantV2(
                version = '2020-04-01',
                authenticator = authenticator
            )
            service.set_service_url('https://api.eu-gb.assistant.watson.cloud.ibm.com/instances/49abc832-b899-4359-aca3-ea100ceb777a')
            assistant_id = '8e3469cd-deaa-465f-8f6d-e1e4cbf7d9c1' # replace with assistant ID

            # Create session.
            session_id = service.create_session(
                assistant_id = assistant_id
            ).get_result()['session_id']

            # Initialize with emptyhi values to start the conversation.
            message_input = {'text': ''}
            current_action = ''


        while current_action != 'end_conversation':
            # Clear any action flag set by the previous response.
            current_action = ''

            # Send message to assistant.
            response = service.message(
                assistant_id,
                session_id,
                input = message_input
            ).get_result()

            # Print the output from dialog, if any. Supports only a single
            # text response.
            if response['output']['generic']:
                if response['output']['generic'][0]['response_type'] == 'text':
                    self.cevap.setText(response['output']['generic'][0]['text'])
            # Check for client actions requested by the assistant.
            if 'actions' in response['output']:
                if response['output']['actions'][0]['type'] == 'client':
                    current_action = response['output']['actions'][0]['name']

            # If we're not done, prompt for next round of input.
            if current_action != 'end_conversation': 

                user_input=self.yazi_alani.text()
                message_input = {
                    'text': user_input
                }

        # We're done, so we delete the session.
        service.delete_session(
            assistant_id = assistant_id,
            session_id = session_id
        )




    def gonder(self):
        return self.yazi_alani.text()


app=QtWidgets.QApplication(sys.argv)

pencere=Pencere()

sys.exit(app.exec_())    

В этом коде я использую окно ввода больше не зависает, я не хочу использовать консоль

как я могу это исправить или что-то

if current_action != 'end_conversation': 
    input("->")
    user_input=self.yazi_alani.text()
    message_input = {
        'text': user_input
    }

1 Ответ

0 голосов
/ 30 апреля 2020

Вам не нужно запускать трудоемкие задачи, так как они замораживают GUI, если задача очень трудоемкая, вы должны запустить ее в другом потоке и отправить результат в поток GUI, используя сигналы, как показано в следующем примере:

import threading
import sys

from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

from PyQt5 import QtCore, QtWidgets


class IBMWatsonManager(QtCore.QObject):
    connected = QtCore.pyqtSignal()
    disconnected = QtCore.pyqtSignal()
    messageChanged = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)

        self._assistant_id = "8e3469cd-deaa-465f-8f6d-e1e4cbf7d9c1"
        self._session_id = ""
        self._service = None
        self.connected.connect(self.send_message)

        self._is_active = False

    @property
    def assistant_id(self):
        return self._assistant_id

    @property
    def session_id(self):
        return self._session_id

    @property
    def service(self):
        return self._service

    @property
    def is_active(self):
        return self._is_active

    def create_session(self):
        threading.Thread(target=self._create_session, daemon=True).start()

    def _create_session(self):
        authenticator = IAMAuthenticator(
            "4CpKAKUsLRpYvcUX_nQRR1MGnYM1WqJLUhE4XS-p4B7Y"
        )  # replace with API key
        self._service = AssistantV2(version="2020-04-01", authenticator=authenticator)
        self.service.set_service_url(
            "https://api.eu-gb.assistant.watson.cloud.ibm.com/instances/49abc832-b899-4359-aca3-ea100ceb777a"
        )

        self._session_id = self.service.create_session(
            assistant_id=self.assistant_id
        ).get_result()["session_id"]
        self._is_active = True
        self.connected.emit()

    @QtCore.pyqtSlot()
    @QtCore.pyqtSlot(str)
    def send_message(self, text=""):
        threading.Thread(target=self._send_message, args=(text,), daemon=True).start()

    def _send_message(self, text):
        response = self.service.message(
            self.assistant_id, self.session_id, input={"text": text}
        ).get_result()
        generic = response["output"]["generic"]
        if generic:
            t = "\n".join([g["text"] for g in generic if g["response_type"] == "text"])
            self.messageChanged.emit(t)
        output = response["output"]
        if "actions" in output:
            client_response = output["actions"][0]
            if client_response["type"] == "client":
                current_action = client_response["name"]
                if current_action == "end_conversation":
                    self._close_session()
                    self._is_active = False
                    self.disconnected.emit()

    def _close_session(self):
        self.service.delete_session(
            assistant_id=self.assistant_id, session_id=self.session_id
        )


class Widget(QtWidgets.QWidget):
    sendSignal = QtCore.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.message_le = QtWidgets.QLineEdit()
        self.send_button = QtWidgets.QPushButton("Send")

        self.message_lbl = QtWidgets.QLabel()

        v_box = QtWidgets.QVBoxLayout()
        v_box.addWidget(self.message_lbl)
        v_box.addStretch()
        v_box.addWidget(self.message_le)
        v_box.addWidget(self.send_button)

        h_box = QtWidgets.QHBoxLayout(self)
        h_box.addStretch()
        h_box.addLayout(v_box)

        self.disable()

        self.setGeometry(200, 200, 500, 500)

        self.send_button.clicked.connect(self.on_clicked)

    @QtCore.pyqtSlot()
    def enable(self):
        self.message_le.setEnabled(True)
        self.send_button.setEnabled(True)

    @QtCore.pyqtSlot()
    def disable(self):
        self.message_le.setEnabled(False)
        self.send_button.setEnabled(False)

    @QtCore.pyqtSlot()
    def on_clicked(self):
        text = self.message_le.text()
        self.sendSignal.emit(text)
        self.message_le.clear()

    @QtCore.pyqtSlot(str)
    def set_message(self, text):
        self.message_lbl.setText(text)


if __name__ == "__main__":

    app = QtWidgets.QApplication(sys.argv)

    w = Widget()
    w.show()

    manager = IBMWatsonManager()

    manager.connected.connect(w.enable)
    manager.disconnected.connect(w.disable)
    w.sendSignal.connect(manager.send_message)
    manager.messageChanged.connect(w.set_message)

    manager.create_session()

    sys.exit(app.exec_())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...