Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Qprocess not working on Windows (works fine on Linux and OSX)
Forum Updated to NodeBB v4.3 + New Features

Qprocess not working on Windows (works fine on Linux and OSX)

Scheduled Pinned Locked Moved Solved Qt for Python
6 Posts 2 Posters 706 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Dost
    wrote on last edited by
    #1

    I am trying to spawn a subprocess from my main programm using the QProcess module. This process should send information to the main programm. My code works fine for Linux and OSX but doesn't work on Windows. It seems like the commands for executing the the process aren't even read since a wrong path does not trigger any Error messages.

    I have already asked this question on stackoverflow but so far no suggestion worked out.
    link: https://stackoverflow.com/questions/71881833/qprocess-wont-start-process-on-windows-but-works-on-linux-and-osx?noredirect=1#comment127039137_71881833

    here my code for the main program:

    import sys
    from PyQt5 import QtCore, QtWidgets, QtGui
    from PyQt5 import uic
    import pickle
    
    class MyGuiApp(QtWidgets.QMainWindow):
        def __init__(self):
            QtWidgets.QMainWindow.__init__(self)
            self.ui = uic.loadUi('process_gui.ui', self)
    
            
            # Set puchButtons
            self.stop_pB.setEnabled(False)
            self.start_pB.clicked.connect(self.start_measurement)
            self.stop_pB.clicked.connect(self.stop_measurement)
    
            # Initialising Subprocess
            self.my_process = QtCore.QProcess()
            self.my_process.readyReadStandardOutput.connect(self.new_data)
    
        def start_measurement(self):
            self.stop_pB.setEnabled(True)
            self.start_pB.setEnabled(False)
    
            self.my_process.start('python3', ['C:Users/me/desktop/dummyfolder/main_subprocess.py'])
    
        def stop_measurement(self):
            self.stop_pB.setEnabled(False)
            self.start_pB.setEnabled(True)
    
            self.my_process.terminate()
    
        def new_data(self):
            data = self.my_process.readAllStandardOutput()
            # unpickle data -> string
            stdout_str = pickle.loads(data)
    
            self.label.setText(stdout_str)
    
    
    if __name__=='__main__':
        app = QtWidgets.QApplication(sys.argv)
        mainWindow = MyGuiApp()
        mainWindow.show()
        sys.exit(app.exec_())
    

    here the code for my subprocess:

     import time
       import sys
       import pickle
    
       index = 0
       while True:
          start = time.time()
    
          sys.stdout.buffer.write(pickle.dumps(str(index)))
          sys.stdout.flush()
    
          index = index + 1
          time.sleep(0.5-(time.time()-start)) # sets loop runtime to 0.5 secs
    

    and in case someone wants to run the code here the .ui code:

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <layout class="QGridLayout" name="gridLayout_2">
        <item row="0" column="0">
         <widget class="QGroupBox" name="groupBox">
          <property name="title">
           <string>GroupBox</string>
          </property>
          <layout class="QGridLayout" name="gridLayout">
           <item row="0" column="0">
            <layout class="QVBoxLayout" name="verticalLayout">
             <item>
              <widget class="QPushButton" name="start_pB">
               <property name="text">
                <string>Start</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QPushButton" name="stop_pB">
               <property name="text">
                <string>Stop</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QLabel" name="label">
               <property name="font">
                <font>
                 <pointsize>20</pointsize>
                </font>
               </property>
               <property name="text">
                <string>DATA</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </item>
       </layout>
      </widget>
      <widget class="QMenuBar" name="menubar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>800</width>
         <height>22</height>
        </rect>
       </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
     </widget>
     <resources/>
     <connections/>
    </ui>
    
    JonBJ 1 Reply Last reply
    0
    • D Dost

      I am trying to spawn a subprocess from my main programm using the QProcess module. This process should send information to the main programm. My code works fine for Linux and OSX but doesn't work on Windows. It seems like the commands for executing the the process aren't even read since a wrong path does not trigger any Error messages.

      I have already asked this question on stackoverflow but so far no suggestion worked out.
      link: https://stackoverflow.com/questions/71881833/qprocess-wont-start-process-on-windows-but-works-on-linux-and-osx?noredirect=1#comment127039137_71881833

      here my code for the main program:

      import sys
      from PyQt5 import QtCore, QtWidgets, QtGui
      from PyQt5 import uic
      import pickle
      
      class MyGuiApp(QtWidgets.QMainWindow):
          def __init__(self):
              QtWidgets.QMainWindow.__init__(self)
              self.ui = uic.loadUi('process_gui.ui', self)
      
              
              # Set puchButtons
              self.stop_pB.setEnabled(False)
              self.start_pB.clicked.connect(self.start_measurement)
              self.stop_pB.clicked.connect(self.stop_measurement)
      
              # Initialising Subprocess
              self.my_process = QtCore.QProcess()
              self.my_process.readyReadStandardOutput.connect(self.new_data)
      
          def start_measurement(self):
              self.stop_pB.setEnabled(True)
              self.start_pB.setEnabled(False)
      
              self.my_process.start('python3', ['C:Users/me/desktop/dummyfolder/main_subprocess.py'])
      
          def stop_measurement(self):
              self.stop_pB.setEnabled(False)
              self.start_pB.setEnabled(True)
      
              self.my_process.terminate()
      
          def new_data(self):
              data = self.my_process.readAllStandardOutput()
              # unpickle data -> string
              stdout_str = pickle.loads(data)
      
              self.label.setText(stdout_str)
      
      
      if __name__=='__main__':
          app = QtWidgets.QApplication(sys.argv)
          mainWindow = MyGuiApp()
          mainWindow.show()
          sys.exit(app.exec_())
      

      here the code for my subprocess:

       import time
         import sys
         import pickle
      
         index = 0
         while True:
            start = time.time()
      
            sys.stdout.buffer.write(pickle.dumps(str(index)))
            sys.stdout.flush()
      
            index = index + 1
            time.sleep(0.5-(time.time()-start)) # sets loop runtime to 0.5 secs
      

      and in case someone wants to run the code here the .ui code:

      <?xml version="1.0" encoding="UTF-8"?>
      <ui version="4.0">
       <class>MainWindow</class>
       <widget class="QMainWindow" name="MainWindow">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>800</width>
          <height>600</height>
         </rect>
        </property>
        <property name="windowTitle">
         <string>MainWindow</string>
        </property>
        <widget class="QWidget" name="centralwidget">
         <layout class="QGridLayout" name="gridLayout_2">
          <item row="0" column="0">
           <widget class="QGroupBox" name="groupBox">
            <property name="title">
             <string>GroupBox</string>
            </property>
            <layout class="QGridLayout" name="gridLayout">
             <item row="0" column="0">
              <layout class="QVBoxLayout" name="verticalLayout">
               <item>
                <widget class="QPushButton" name="start_pB">
                 <property name="text">
                  <string>Start</string>
                 </property>
                </widget>
               </item>
               <item>
                <widget class="QPushButton" name="stop_pB">
                 <property name="text">
                  <string>Stop</string>
                 </property>
                </widget>
               </item>
               <item>
                <widget class="QLabel" name="label">
                 <property name="font">
                  <font>
                   <pointsize>20</pointsize>
                  </font>
                 </property>
                 <property name="text">
                  <string>DATA</string>
                 </property>
                </widget>
               </item>
              </layout>
             </item>
            </layout>
           </widget>
          </item>
         </layout>
        </widget>
        <widget class="QMenuBar" name="menubar">
         <property name="geometry">
          <rect>
           <x>0</x>
           <y>0</y>
           <width>800</width>
           <height>22</height>
          </rect>
         </property>
        </widget>
        <widget class="QStatusBar" name="statusbar"/>
       </widget>
       <resources/>
       <connections/>
      </ui>
      
      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @Dost said in Qprocess not working on Windows (works fine on Linux and OSX):

      'C:Users/me/desktop/dummyfolder/main_subprocess.py'

      This is not an absolute path, and doubtless not what you intended, so hardly surprising.

      If you had read from the QProcess standard error, and checked for an error, as you should always do, you would doubtless have seen the appropriate error message saying "it cannot be found". Before you say it's not the path but something else, connect to QProcess::errorOccurred() & readyReadStandardError(); if still unclear, connect to started(), stateChanged() & finished().

      Put a print("Reached\n") in start_measurement(). And create a file somewhere as the first statement in your .py subprocess script, so that we know whether it has actually run or not rather than relying on whether you think you see any output from it.

      1 Reply Last reply
      2
      • D Offline
        D Offline
        Dost
        wrote on last edited by
        #3

        Thank for your awnser. Sadly i was slopy when editing the path, in my program i am actually using an absolute path. I also did the trick with the file already so i knew that the subprocess didn't even start.

        I added what you have suggested now, with the result: error code 0 (The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.)

        I double checked the file path so there should be no problem with that. Concerning the insufficient permissions, what to do about that?

        updated code:

        import sys
        from PyQt5 import QtCore, QtWidgets
        from PyQt5 import uic
        import pickle
        
        
        class MyGuiApp(QtWidgets.QMainWindow):
            def __init__(self):
                print('too far')
                QtWidgets.QMainWindow.__init__(self)
                self.ui = uic.loadUi('process_gui.ui', self)
        
                # Settings pushButtons
                self.stop_pB.setEnabled(False)
                self.start_pB.clicked.connect(self.start_measurement)
                self.stop_pB.clicked.connect(self.stop_measurement)
        
                # Initialising Subprocess
                self.my_process = QtCore.QProcess()
                self.my_process.readyReadStandardOutput.connect(self.new_data)
                self.my_process.readyReadStandardError.connect(self.process_error)
                self.my_process.started.connect(self.started)
                self.my_process.errorOccurred.connect(self.error)
                # tried another way, both didn't work
                self.my_process.setProgram('python3')
                self.my_process.setArguments([r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py'])
                print(str(self.my_process.state()), 'State (init)')
        
            def start_measurement(self):
                self.stop_pB.setEnabled(True)
                self.start_pB.setEnabled(False)
        
        
                #self.my_process.start('python3', [r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py'])
                self.my_process.start()
                print(str(self.my_process.state()), 'State (start_measurement)')
        
                print('reached')
        
            def stop_measurement(self):
                self.stop_pB.setEnabled(False)
                self.start_pB.setEnabled(True)
        
                self.my_process.terminate()
        
            def new_data(self):
                data = self.my_process.readAllStandardOutput()
                # unpickle data -> string
                stdout_str = pickle.loads(data)
        
                self.label.setText(stdout_str)
        
            def process_error(self):
                error = self.my_process.readAllStandardError()
                print(error)
        
            def started(self):
                print('process started')
        
            def error(self):
                print('error occurred {}'.format(self.my_process.error()))
        
        
        
        if __name__ == '__main__':
            app = QtWidgets.QApplication(sys.argv)
            mainWindow = MyGuiApp()
            mainWindow.show()
            sys.exit(app.exec_())
        
        JonBJ 1 Reply Last reply
        0
        • D Dost

          Thank for your awnser. Sadly i was slopy when editing the path, in my program i am actually using an absolute path. I also did the trick with the file already so i knew that the subprocess didn't even start.

          I added what you have suggested now, with the result: error code 0 (The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.)

          I double checked the file path so there should be no problem with that. Concerning the insufficient permissions, what to do about that?

          updated code:

          import sys
          from PyQt5 import QtCore, QtWidgets
          from PyQt5 import uic
          import pickle
          
          
          class MyGuiApp(QtWidgets.QMainWindow):
              def __init__(self):
                  print('too far')
                  QtWidgets.QMainWindow.__init__(self)
                  self.ui = uic.loadUi('process_gui.ui', self)
          
                  # Settings pushButtons
                  self.stop_pB.setEnabled(False)
                  self.start_pB.clicked.connect(self.start_measurement)
                  self.stop_pB.clicked.connect(self.stop_measurement)
          
                  # Initialising Subprocess
                  self.my_process = QtCore.QProcess()
                  self.my_process.readyReadStandardOutput.connect(self.new_data)
                  self.my_process.readyReadStandardError.connect(self.process_error)
                  self.my_process.started.connect(self.started)
                  self.my_process.errorOccurred.connect(self.error)
                  # tried another way, both didn't work
                  self.my_process.setProgram('python3')
                  self.my_process.setArguments([r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py'])
                  print(str(self.my_process.state()), 'State (init)')
          
              def start_measurement(self):
                  self.stop_pB.setEnabled(True)
                  self.start_pB.setEnabled(False)
          
          
                  #self.my_process.start('python3', [r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py'])
                  self.my_process.start()
                  print(str(self.my_process.state()), 'State (start_measurement)')
          
                  print('reached')
          
              def stop_measurement(self):
                  self.stop_pB.setEnabled(False)
                  self.start_pB.setEnabled(True)
          
                  self.my_process.terminate()
          
              def new_data(self):
                  data = self.my_process.readAllStandardOutput()
                  # unpickle data -> string
                  stdout_str = pickle.loads(data)
          
                  self.label.setText(stdout_str)
          
              def process_error(self):
                  error = self.my_process.readAllStandardError()
                  print(error)
          
              def started(self):
                  print('process started')
          
              def error(self):
                  print('error occurred {}'.format(self.my_process.error()))
          
          
          
          if __name__ == '__main__':
              app = QtWidgets.QApplication(sys.argv)
              mainWindow = MyGuiApp()
              mainWindow.show()
              sys.exit(app.exec_())
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Dost said in Qprocess not working on Windows (works fine on Linux and OSX):

          I added what you have suggested now, with the result: error code 0 (The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.)

          Well whatever the reason that seems to be the cause if you are saying that is the error text it reports.

          I am not clear from what you write where that message came from? From process_error()? From error()? Did you get any message from started()?

          The "invoked program" in this case is python3, not your .py script file argument to it.

          Let's start by removing the script. I believe that, say, python3 -V just reports some stuff and exits. Try that, or something similar. Does it run, do you get its output? Assuming not, we know where we are. Are you sure python3 is in some directory on your PATH when invoked from your Qt app? Can it find whatever DLLs it needs correctly from that PATH? Where is python3, is it a .exe or a .bat file? Does it help to give the full path to the desired python3.exe instead of just your plain python3 to run it?

          Go find something completely different from python3 to execute, and verify that does work as expected.

          1 Reply Last reply
          1
          • D Offline
            D Offline
            Dost
            wrote on last edited by
            #5

            Again thank you for your answer. As you already assumed the problem was that i had to add the path leading to the python.exe.

            The error was triggered by errorConnect and there was no message from started().

            A new problem occured as the Qprocess wont stop when terminate() (state stays 2 before and after the call) is called, but it works with kill() for me.

            JonBJ 1 Reply Last reply
            0
            • D Dost

              Again thank you for your answer. As you already assumed the problem was that i had to add the path leading to the python.exe.

              The error was triggered by errorConnect and there was no message from started().

              A new problem occured as the Qprocess wont stop when terminate() (state stays 2 before and after the call) is called, but it works with kill() for me.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @Dost
              Good for the PATH issue. Consider putting python3 on your PATH rather than having to typing the full path to it.

              A new problem occured as the Qprocess wont stop when terminate() (state stays 2 before and after the call) is called, but it works with kill() for me.

              This is usual for Windows, for any command-line program like python3:

              Console applications on Windows that do not run an event loop, or whose event loop does not handle the WM_CLOSE message, can only be terminated by calling kill().

              Really it's naughty to need to use either terminate() or particularly kill(). Presumably your Python script runs forever and does not have a nice means to exit it.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved