2017-01-08 13 views
-1

Я работаю над графическим интерфейсом в python 3.5 с PyQt5 для небольшого бот-чата. Проблема заключается в том, что предварительная обработка, пост-обработка и мозг занимают слишком много времени, чтобы вернуть ответ для введенного пользователем ввода.Интерфейс PyQt5 не отвечает в ожидании слишком долго

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

я также упомянуть, что я не использую цикл, так как мое сообщение является в любом случае, из окна ввода, и я также пытался использовать __QtCore.QCoreApplication.processEvents() __, но все же зависает. – student0495

+1

Вам необходимо предоставить минимальный полный проверяемый пример: http://stackoverflow.com/help/mcve –

ответ

2

Медленные функции, такие как sleep, всегда будут блокироваться, если они не выполняются асинхронно в другом потоке.

Если вы хотите избежать потоков, обходным путем является разбить медленную функцию. В вашем случае это может выглядеть следующим образом:

for _ in range(20): 
    sleep(1) 
    self.app.processEvents() 

где self.app является ссылкой на экземпляр QApplication. Это решение немного взломанно, так как оно просто приведет к 20 коротким зависаниям, а не одному длинному зависанию.

Если вы хотите использовать этот подход для своей функции мозга, вам понадобится его, чтобы разбить его аналогичным образом. Помимо этого вам понадобится использовать поточный подход.

+0

Я пробовал решение, но не помогло. МЫ, Я реализовал поточную версию, все еще зависает, но лучше работает для других модулей, и он печатает ответ, когда он готов, даже если это займет много времени. – student0495

+0

Если вы публикуете код с резьбой, мы можем понять, почему это не работает отлично. – 101

+0

На самом деле я заработал, но я этого не знал, потому что я использовал сон, но интегрировался с другими модулями и не спал, даже если время ответа больше, приложение больше не замерзает. Я скоро опубликую обновленную версию с резьбой (весь код на этот раз) для лучшего улучшения и других решений :) – student0495

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/