带有 pyqt5 window 的 IBM Watson 在 while 循环中冻结
IBM Watson with pyqt5 window is freezing in the while loop
我的 window 在 while 循环中冻结我如何修复它或如何等待输入进入循环如果我添加输入(“”)一些程序不再冻结但我不想使用控制台。
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_())
在这段代码中我使用输入 window 不再冻结我不想使用控制台
我该如何解决这个问题
if current_action != 'end_conversation':
input("->")
user_input=self.yazi_alani.text()
message_input = {
'text': user_input
}
您不必 运行 耗时的任务,因为它们会冻结 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_())
我的 window 在 while 循环中冻结我如何修复它或如何等待输入进入循环如果我添加输入(“”)一些程序不再冻结但我不想使用控制台。
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_())
在这段代码中我使用输入 window 不再冻结我不想使用控制台
我该如何解决这个问题
if current_action != 'end_conversation':
input("->")
user_input=self.yazi_alani.text()
message_input = {
'text': user_input
}
您不必 运行 耗时的任务,因为它们会冻结 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_())