2017-02-12 18 views
0

私はopenOCDを使用するためのGUIを書いています。コードスニペットは、openOCDサーバーを起動し、その出力をtextEditウィジェットに表示することになっていました。 しかし、エラーメッセージは表示されませんが、プロセスは意図したとおりに機能しません。私はps -auxをチェックし、openOCDプロセスが存在しないことを示しています。 プロセスの状態は '1'であり、ドキュメントに従ってプロセスがクラッシュしたことを意味します。どこが間違っていますか?PyQtでQProcessが失敗する理由

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

'プリント(STR(self.JTAG_ServerProcess.errorString()))':
はERRORTEXT()メソッドを参照してください。 'state()'の戻り値はエラーとは何の関係もありません。状態が「1」の場合、これは「QProcess.Starting」に相当します。 – ekhumoro

答えて

0

未テストですが、以前はQProcessをラップしていたので、エラーが発生したときに少し詳しい情報が得られました。

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 
関連する問題