Home > Back-end >  QProcess won't start process on Windows (but works on Linux and OSX)
QProcess won't start process on Windows (but works on Linux and OSX)

Time:04-18

I am currently working on a signal analyzing program with a GUI, which should run on Linux, OSX and Windows. For some reason this program won't run on Windows, but I don't get any Error Messages. More precisely my main program (GUI) fails to spawn my subprocess that should analyze the data and send the results to the GUI.

The only thing I found online was that Windows needs

if __name__ == '__main__':

to run processes correctly if they are created using the multiprocessing module. Sadly, adding this part didn't solve the problem for Qprocess.

I wrote a pretty simple script that has the same problem and communicates like my complex scripts.

Here my main GUI process:

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', ['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 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 here the .ui file in case someone wants to run my code:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget  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  name="centralwidget">
   <layout  name="gridLayout_2">
    <item row="0" column="0">
     <widget  name="groupBox">
      <property name="title">
       <string>GroupBox</string>
      </property>
      <layout  name="gridLayout">
       <item row="0" column="0">
        <layout  name="verticalLayout">
         <item>
          <widget  name="start_pB">
           <property name="text">
            <string>Start</string>
           </property>
          </widget>
         </item>
         <item>
          <widget  name="stop_pB">
           <property name="text">
            <string>Stop</string>
           </property>
          </widget>
         </item>
         <item>
          <widget  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  name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget  name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

CodePudding user response:

I run this in a windows 10 environment using the VS code editor.

I made no changes to the code whatsoever. I did this:

  1. I created the process_gui.ui file
  2. I created the main_subprocess.py file
  3. I replicted the code in the question

This works.

It produces this: enter image description here

And when i press the start button it initiates a counter like this:

enter image description here

So i can confirm that the code does run on windows. I hope that this helps you or at least confirms that it does run.

Given that the code works, you should not look at the environment settings.

CodePudding user response:

I solved the issue with the help of the qt-forum and @D.L's comment: https://forum.qt.io/topic/135863/qprocess-not-working-on-windows-works-fine-on-linux-and-osx/5

Additional to if __name__=='__main__': one has to change 2 things in order to run my code on Windows.

  1. Don't call python3 but give Qprocess the absolute path to the python.exe. Note that even though im running python3 it is called python.exe inside a Python3X folder, like: r'C:\Users\me\AppData\AppData\Local\Programs\Python\Python39\python'
  2. The same is true for the script you want run. Give the QProcess the whole absoltue path, like: r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py'.

For some reason QProcess::terminate(), which should be triggered once you press 'Stop', does not work now. The state of the Subprocess stays in 2 (The process is running and is ready for reading and writing.) but QProcess::kill() works fine for me.

`

  • Related