QProcess PyQt5 TypeError
QProcess PyQt5 TypeError
我有一个使用大量 QProcess 的应用程序,有时同时使用两个进程 运行。这就是为什么我有很多 readyReadStandardOutput.connect() 的功能。所以我的想法是为类似情况创建两个或三个 classes 并大量减少代码。我已经能够检查在这个问题中,有一个我喜欢的解决方案
还有一个:
我试图创建一个 class 可以帮助我从第一个 link 的 class 开始,但是我没有成功,因为它会产生错误
QObject::connect: Cannot connect ProcessOutputReader::produce_output(QString) to (null)::append_output(QString)
Traceback (most recent call last):
File "process2.py", line 22, in funRun
self.process.run_process()
File "process2.py", line 40, in run_process
self.process.produce_output.connect(self.append_output)
TypeError: connect() failed between ProcessOutputReader.produce_output[str] and append_output()
这是我的代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class windowProcess(QMainWindow):
def __init__(self):
super(windowProcess, self).__init__()
self.setWindowTitle("Windows Process")
self.resize(475, 253)
self.btn_run = QPushButton("run",self)
self.btn_run.setGeometry(388, 20, 75, 25)
self.text_edit = QTextEdit(self)
self.text_edit.setGeometry(20, 50, 441, 191)
self.btn_run.clicked.connect(self.funRun)
def funRun(self):
self.process = myClassProcess()
self.process.run_process()
@pyqtSlot(str)
def append_output(self, text):
self.text_edit.append(text)
@pyqtSlot(str)
def append_error(self, text):
self.text_edit.append(text)
class myClassProcess(object):
def __init__(self, parent=None):
self.info = []
def run_process(self):
self.process = ProcessOutputReader()
cmd = "ping www.google.com"
self.process.produce_output.connect(self.append_output)
self.process.produce_error.connect(self.append_error)
self.process.start(cmd)
@pyqtSlot(str)
def append_output(self, text):
print(text)
self.info.append(text)
#return text
@pyqtSlot(str)
def append_error(self, text):
self.info.append(text)
#return text
def getInfo(self):
print(self.info)
class ProcessOutputReader(QProcess):
produce_output = pyqtSignal(str)
produce_error = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent=parent)
codec = QTextCodec.codecForLocale()
self._decoder_stdout = codec.makeDecoder()
# only necessary when stderr channel isn't merged into stdout:
self._decoder_stderr = codec.makeDecoder()
self.readyReadStandardOutput.connect(self._ready_read_standard_output)
# only necessary when stderr channel isn't merged into stdout:
self.readyReadStandardError.connect(self._ready_read_standard_error)
@pyqtSlot()
def _ready_read_standard_output(self):
raw_bytes = self.readAllStandardOutput()
text = self._decoder_stdout.toUnicode(raw_bytes)
self.produce_output.emit(text)
# only necessary when stderr channel isn't merged into stdout:
@pyqtSlot()
def _ready_read_standard_error(self):
raw_bytes = self.readAllStandardError()
text = self._decoder_stderr.toUnicode(raw_bytes)
self.produce_error.emit(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
ventana = windowProcess()
ventana.show()
sys.exit(app.exec_())
pyqtSlot 装饰器仅对 QObject 有意义,在我的例子中,myClassProcess 不会导致您指出的问题。
鉴于此,有 2 个解决方案:
不要在 myClassProcess 的 append_output
和 append_error
方法中使用 @pyqtSlot
。
或者将 myClassProcess 设为 QObject:
class myClassProcess(<b>QObject</b>):
def __init__(self, parent=None):
<b>super().__init__(parent)</b>
self.info = []
我有一个使用大量 QProcess 的应用程序,有时同时使用两个进程 运行。这就是为什么我有很多 readyReadStandardOutput.connect() 的功能。所以我的想法是为类似情况创建两个或三个 classes 并大量减少代码。我已经能够检查在这个问题中,有一个我喜欢的解决方案
还有一个:
我试图创建一个 class 可以帮助我从第一个 link 的 class 开始,但是我没有成功,因为它会产生错误
QObject::connect: Cannot connect ProcessOutputReader::produce_output(QString) to (null)::append_output(QString)
Traceback (most recent call last):
File "process2.py", line 22, in funRun
self.process.run_process()
File "process2.py", line 40, in run_process
self.process.produce_output.connect(self.append_output)
TypeError: connect() failed between ProcessOutputReader.produce_output[str] and append_output()
这是我的代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class windowProcess(QMainWindow):
def __init__(self):
super(windowProcess, self).__init__()
self.setWindowTitle("Windows Process")
self.resize(475, 253)
self.btn_run = QPushButton("run",self)
self.btn_run.setGeometry(388, 20, 75, 25)
self.text_edit = QTextEdit(self)
self.text_edit.setGeometry(20, 50, 441, 191)
self.btn_run.clicked.connect(self.funRun)
def funRun(self):
self.process = myClassProcess()
self.process.run_process()
@pyqtSlot(str)
def append_output(self, text):
self.text_edit.append(text)
@pyqtSlot(str)
def append_error(self, text):
self.text_edit.append(text)
class myClassProcess(object):
def __init__(self, parent=None):
self.info = []
def run_process(self):
self.process = ProcessOutputReader()
cmd = "ping www.google.com"
self.process.produce_output.connect(self.append_output)
self.process.produce_error.connect(self.append_error)
self.process.start(cmd)
@pyqtSlot(str)
def append_output(self, text):
print(text)
self.info.append(text)
#return text
@pyqtSlot(str)
def append_error(self, text):
self.info.append(text)
#return text
def getInfo(self):
print(self.info)
class ProcessOutputReader(QProcess):
produce_output = pyqtSignal(str)
produce_error = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent=parent)
codec = QTextCodec.codecForLocale()
self._decoder_stdout = codec.makeDecoder()
# only necessary when stderr channel isn't merged into stdout:
self._decoder_stderr = codec.makeDecoder()
self.readyReadStandardOutput.connect(self._ready_read_standard_output)
# only necessary when stderr channel isn't merged into stdout:
self.readyReadStandardError.connect(self._ready_read_standard_error)
@pyqtSlot()
def _ready_read_standard_output(self):
raw_bytes = self.readAllStandardOutput()
text = self._decoder_stdout.toUnicode(raw_bytes)
self.produce_output.emit(text)
# only necessary when stderr channel isn't merged into stdout:
@pyqtSlot()
def _ready_read_standard_error(self):
raw_bytes = self.readAllStandardError()
text = self._decoder_stderr.toUnicode(raw_bytes)
self.produce_error.emit(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
ventana = windowProcess()
ventana.show()
sys.exit(app.exec_())
pyqtSlot 装饰器仅对 QObject 有意义,在我的例子中,myClassProcess 不会导致您指出的问题。
鉴于此,有 2 个解决方案:
不要在 myClassProcess 的
append_output
和append_error
方法中使用@pyqtSlot
。或者将 myClassProcess 设为 QObject:
class myClassProcess(<b>QObject</b>): def __init__(self, parent=None): <b>super().__init__(parent)</b> self.info = []