我正在编写一个使用openOCD的GUI。代码片段应该启动openOCD服务器并在textEdit小部件上显示它的输出。
但是,虽然我没有看到任何错误消息,但该过程无法按预期工作。我检查了ps -aux
,它将openOCD进程显示为已失效。
进程状态为“1”,根据文档表示进程崩溃。我哪里错了?
class BadgeMain(Ui_MainWindow):
def __init__(self,dialog,parent=None):
Ui_MainWindow.__init__(self)
self.setupUi(dialog)
self.pushButton_JtagStartServer.clicked.connect(self.JTAG_startserver)
self.JTAG_ServerProcess = QtCore.QProcess()
self.JTAG_ServerProcess.readyRead.connect(self.JTAG_dataReady)
def JTAG_dataReady(self):
cursor=self.textEdit_JtagConsole.textCursor()
cursor.movePosition(cursor.End)
cursor.insertText(str(self.Jtag_process.readAll()))
self.textEdit_JtagConsole.ensureCursorVisible()
def JTAG_startserver(self):
self.JTAG_ServerProcess.start('openocd',['-c','telnet_port 4444','-f','cfg/ftdi.cfg','-f','cfg/stm32.cfg'])
print(str(self.JTAG_ServerProcess.state()))
答案 0 :(得分:0)
未经测试,但我之前已经包装了QProcess,因此我可以在错误时获得更多信息 请参见errorText()方法:
class Process(QtCore.QProcess):
"""
Makes QProcess a bit more usable (to my mind) in the following ways:
- Automatically frees memory when it's spent (see __singleshot).
- Makes stderr and stdout more-like 'properties' of the object, rather than weird streams/buffers that evaporate after you read them!
- Abstracts success & failure such that succeeded() means 'everything succeeded' and failed() to mean '*something* failed'.
- All error text is available from a single call, regardless of error-origin (QProcess; the program invoked; or the underlying device).
- Defines __finished to mean 'we either succeeded or failed but, either way, it's all over'.
- Added various helper methods such as isValid(), isRunning(), etc.
"""
def __init__(self, singleshot=True, *args, **kwargs):
super().__init__(*args, **kwargs)
# Important that these slots are connected first, so our responses are readied first.
self.finished.connect(self.on_finished)
self.error.connect(self.on_error)
self.__singleshot = singleshot
self.__finished = False
self.__stdoutText = ""
self.__stderrText = ""
self.__QProcessErrorText = ""
self.__QIODeviceErrorText = ""
self.__QIODeviceDefaultErrorString = self.errorString() # So we can later avoid QIODevice's pessimistic, spurious default message of 'Unknown Error'.
self.__succeeded = False
def on_error(self, error):
self.__finished = True
self.__succeeded = False # .. probably overkill.. (probably already False..)
errorMap = {self.FailedToStart: "The process failed to start.",
self.Crashed: "The process crashed some time after starting successfully.",
self.Timedout: "The last waitFor...() function timed out.",
self.WriteError: "An error occurred when attempting to write to the process.",
self.ReadError: "An error occurred when attempting to read from the process.",
self.UnknownError: "An unknown error occurred."}
self.__QProcessErrorText = errorMap[error]
if self.__singleshot: self.deleteLater() ## Kinda handy for memory-management...
def on_finished(self, exitCode, exitStatus):
self.__finished = True
self.__succeeded = (exitCode == 0) & (exitStatus == self.NormalExit)
if self.__singleshot: self.deleteLater() ## Kinda handy for memory-management...
def outputText(self):
# Drain the stdout buffer into local instance variable..
self.__stdoutText += str(self.readAllStandardOutput(), encoding='utf-8')
return self.__stdoutText
def stdErrText(self):
# Drain the stderr buffer into local instance variable..
self.__stderrText += str(self.readAllStandardError(), encoding='utf-8')
return self.__stderrText
def errorText(self, delimiter=". "):
# Returns string detailing error from any potential error source (the program; the QProcess; the underlying QIODevice).
errorSources = {"stderr": self.stdErrText(),
"QProcessErrorText": self.__QProcessErrorText,
"QIODeviceErrorText": self.errorString() if not self.__QIODeviceDefaultErrorString else "" } # Drop QIODevice's spurious default message of ~'Unknown error'.
# Note that error texts are stripped, so they have to be substantive...
response = delimiter.join(": ".join([key, value.strip()]) for (key, value) in sorted(errorSources.items()) if value)
return response
def succeeded(self):
return self.__finished and self.__succeeded and (not self.stdErrText()) # stdErr checked because of edge case where QProcess claims to finish and succeed (but writes its own failure to stderr!) -- e.g. "QProcessPrivate::execChild() failed to chdir"...
def failed(self):
return self.__finished and not self.succeeded()
def isValid(self):
try: # An arbitrary interrogation to see if underlying c++ wrapper object has been deleted
self.objectName()
return True
except RuntimeError:
return False
def isRunning(self):
return self.state() == self.Running
def isStarting(self):
return self.state() == self.Starting