为什么即使使用QThreadPool,GUI也会冻结?

时间:2017-05-27 21:59:25

标签: python python-3.x qt pyqt pyqt5

我正在尝试构建一个使用简单QTextEdit的自定义Python控制台小部件。行编辑框接收输入并通过线程中的python解释器运行它。

这是interpreter.py

j

这是main.py

import sys
from io import StringIO, IncrementalNewlineDecoder
from code import InteractiveConsole
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
from stream import NewLineIO

class PythonInterpreter(QObject, InteractiveConsole):
    output = pyqtSignal(str)

    def __init__(self):
        QObject.__init__(self)
        self.l = {}
        InteractiveConsole.__init__(self, self.l)
        self.out = NewLineIO()
        self.out.output.signal_str.connect(self.console)

    def write(self, string):
        self.output.emit(string)

    def runcode(self, codez):
        """
        Reimplementation to capture stdout and stderr
        """
        sys.stdout = self.out
        sys.stderr = self.out
        sys.excepthook = sys.__excepthook__
        result = InteractiveConsole.runcode(self, codez) # Where the magic happens
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        #self.output.emit(self.out.getvalue()) # Send the output
        return result

    @pyqtSlot(str)
    def console(self, string):
        #print(string, file=sys.__stdout__)
        self.output.emit(string)

class JavaScriptInterpreter(QObject):
    pass

每次发出来自import sys from traceback import TracebackException from PyQt5 import QtCore, uic from PyQt5.QtCore import QThread, QThreadPool from PyQt5.QtGui import QFont, QColor from PyQt5.QtWidgets import (QApplication, QDialog, QAction) from PyQt5.Qsci import QsciScintilla, QsciLexerPython, QsciAPIs from interpreters import PythonInterpreter from lexers import PythonLexer from threads import Worker, WorkerSignals from stream import NewLineIO class MainWindow(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.ui = uic.loadUi("main.ui") self.ui.showMaximized() # Code Editor self.font = QFont() self.font.setFamily('Courier New') self.font.setFixedPitch(True) self.font.setPointSize(10) self.ui.code_editor.setFont(self.font) self.lexer = PythonLexer(self.ui, self.font) self.lexer.lock() # Console self.interpreter = PythonInterpreter() self.ui.console_log.isReadOnly() self.ui.console_input.returnPressed.connect(self.send_console_input) self.interpreter.output.connect(self.send_console_log) # Threads self.threadpool = QThreadPool() def send_console_input(self): command = self.ui.console_input.text() self.ui.console_input.clear() worker = Worker(self.interpreter.push, str(command)) worker.signals.result.connect(print) worker.signals.finished.connect(self.thread_complete) #self.interpreter.push(str(command)) self.threadpool.start(worker) print("Thread Count: ", self.threadpool.activeThreadCount(), file=sys.__stdout__) def thread_complete(self): print("Thread Complete !") def send_console_log(self, command): print(command, file=sys.__stdout__) self.ui.console_log.append(command) app = QApplication(sys.argv) window = MainWindow() sys.exit(app.exec_()) 实例的信号时,它都会调用PythonInterpreter,它接收来自解释器上运行的命令的输出。

但是,如果我运行像self.send_console_log之类的大循环作为通过for i in range(10000):print(i)发送给解释器的命令,它将在self.send_console_input中执行print语句,但不是self.send_console_log 1}}。它将冻结直到循环完成,整个事物将被附加到.append()

如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我不确定但是如果GUI是主要部分,它必须先在其他线程之前启动。在GUI之前可能会发生一些或一个踏板。看看这些