我正在使用PyQt5在python 3.5中创建一个用于小型聊天机器人的GUI。我遇到的问题是预处理,后处理和大脑花费了太多时间来回馈用户提供的输入。
GUI非常简单,如下所示:http://prntscr.com/dsxa39它加载速度非常快,无需将其连接到其他模块。我提到在从大脑模块接收答案之前使用睡眠仍然会使它无反应。
self.conversationBox.append("You: "+self.textbox.toPlainText())
self.textbox.setText("")
time.sleep(20)
self.conversationBox.append("Chatbot: " + "message from chatbot")
这是一小段代码,我需要修复的代码。
这是我遇到的错误:http://prnt.sc/dsxcqu
我提到我已经找到了解决方案,我已经找到了我已经尝试过的任何地方,使用睡眠。但同样,这不会起作用,因为它也会使程序无响应。
答案 0 :(得分:2)
慢速函数(例如sleep
)将始终阻止,除非它们在另一个线程中异步运行。
如果你想避免线程,解决方法是打破慢速函数。在您的情况下,它可能看起来像:
for _ in range(20):
sleep(1)
self.app.processEvents()
其中self.app
是对QApplication实例的引用。这个解决方案有点hacky,因为它只会导致20次短暂挂起,而不是一次长时间挂起。
如果你想将这种方法用于你的大脑功能,那么你需要它以类似的方式将其分解。除此之外,您还需要使用线程方法。
答案 1 :(得分:1)
import sys
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QMainWindow, QGridLayout, QLabel, QApplication, QWidget, QTextBrowser, QTextEdit, \
QPushButton, QAction, QLineEdit, QMessageBox
from PyQt5.QtGui import QPalette, QIcon, QColor, QFont
from PyQt5.QtCore import pyqtSlot, Qt
import threading
import time
textboxValue = ""
FinalAnsw = ""
class myThread (threading.Thread):
print ("Start")
def __init__(self):
threading.Thread.__init__(self)
def run(self):
def getAnswer(unString):
#do brain here
time.sleep(10)
return unString
global textboxValue
global FinalAnsw
FinalAnsw = getAnswer(textboxValue)
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'ChatBot'
self.left = 40
self.top = 40
self.width = 650
self.height = 600
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
pal = QPalette();
pal.setColor(QPalette.Background, QColor(40, 40, 40));
self.setAutoFillBackground(True);
self.setPalette(pal);
font = QtGui.QFont()
font.setFamily("FreeMono")
font.setBold(True)
font.setPixelSize(15)
self.setStyleSheet("QTextEdit {color:#3d3838; font-size:12px; font-weight: bold}")
historylabel = QLabel('View your conversation history here: ')
historylabel.setStyleSheet('color: #82ecf9')
historylabel.setFont(font)
messagelabel = QLabel('Enter you message to the chat bot here:')
messagelabel.setStyleSheet('color: #82ecf9')
messagelabel.setFont(font)
self.conversationBox = QTextBrowser(self)
self.textbox = QTextEdit(self)
self.button = QPushButton('Send message', self)
self.button.setStyleSheet(
"QPushButton { background-color:#82ecf9; color: #3d3838 }" "QPushButton:pressed { background-color: black }")
grid = QGridLayout()
grid.setSpacing(10)
self.setLayout(grid)
grid.addWidget(historylabel, 1, 0)
grid.addWidget(self.conversationBox, 2, 0)
grid.addWidget(messagelabel, 3, 0)
grid.addWidget(self.textbox, 4, 0)
grid.addWidget(self.button, 5, 0)
# connect button to function on_click
self.button.clicked.connect(self.on_click)
self.show()
def on_click(self):
global textboxValue
textboxValue = self.textbox.toPlainText()
self.conversationBox.append("You: " + textboxValue)
th = myThread()
th.start()
th.join()
global FinalAnsw
self.conversationBox.append("Rocket: " + FinalAnsw)
self.textbox.setText("")
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
app.exec_()
因此创建一个简单的线程解决了这个问题,上面的代码仍会因为睡眠函数调用而冻结,但是如果用一个持续时间长的普通函数替换它,它就不会再冻结了。它由我的项目的大脑模块测试其功能。
有关构建线程的简单示例,请使用https://www.tutorialspoint.com/python/python_multithreading.htm
对于PyQt GUI,我使用本网站的示例来学习http://zetcode.com/gui/pyqt5/