Search code examples
pythonpyqtmultiprocessingpyqt5

How to use multiprocessing with Pyqt


I am having trouble using multiprocessing with pyqt as it opens up multiple windows and doesn't really exceute the target function. I created my interface in Qt Designer and my example code is as follows:

from multiprocessing import Pool
from PyQt5 import uic, QtWidgets
from PyQt5.QtWidgets import *
import sys

def updater(num):
    print(num)

def main_tracker():
    p = Pool(processes=4)
    data = p.map(updater, range(0, 100))

app=QtWidgets.QApplication(sys.argv)
window = uic.loadUi("tracker.ui")
window.pushButton.clicked.connect(main_tracker)
window.show()
sys.exit(app.exec_())

On running this, the interface opens as normal, but when I click on the pushbutton on the gui it simply opens multiple pyqt windows and doesnt run the functions as expected. How can I get this working so that the multiprocessing works and without opening multiple windows? I have seen kind of similar questions on here but I haven't found one that has a solution addressing my problem.

The code for the ui file:

<?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>365</width>
    <height>134</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>69</x>
      <y>19</y>
      <width>173</width>
      <height>59</height>
     </rect>
    </property>
    <property name="text">
     <string>PushButton</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>365</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

Solution

  • I have two remarks. Always use

    if __name__ == "__main__":
       code here
    

    construction for main file. in your case it will be:

    from multiprocessing import Pool
    from PyQt5 import uic, QtWidgets
    from PyQt5.QtWidgets import *
    import sys
    
    def updater(num):
        print(num)
    
    def main_tracker():
        p = Pool(processes=4)
        data = p.map(updater, range(0, 100))
    
    if __name__ == "__main__":
        app=QtWidgets.QApplication(sys.argv)
        window = uic.loadUi("tracker.ui")
        window.pushButton.clicked.connect(main_tracker)
        window.show()
        sys.exit(app.exec_())
    

    and if you would like to freeze your application (create exec file) on windows then add this lines to your code (or maybe it will fix your error)

    import multiprocessing
    
    multiprocessing.freeze_support()
    

    otherwise you will meet again the problem with multiple window