PyQt5接口在等待太久时没有响应

时间:2017-01-08 10:13:53

标签: python pyqt5 chatbot

我正在使用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

我提到我已经找到了解决方案,我已经找到了我已经尝试过的任何地方,使用睡眠。但同样,这不会起作用,因为它也会使程序无响应。

2 个答案:

答案 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/