0

There will be as many Progress Bars created as there are entities in myList. Clicking Ok button starts as many sub-processes as there are entities in myList.

Problem: 1. It seems there are way more sub-processes started than entities in myList. 2. Unable to update ProgressBar with a line(that's why it is commented):

pb.update_bar( self.pBars[each]['value'] ) 

import sys, os
from PyQt4 import QtCore, QtGui
import threading
import time


class PbWidget(QtGui.QProgressBar):
    def __init__(self, parent=None, total=20):
        super(PbWidget, self).__init__()
        self.setMinimum(1)
        self.setMaximum(total)        
        self._active = False  

    def update_bar(self, to_add_number):
        while True:
            time.sleep(0.01)
            value = self.value() + to_add_number            
            self.setValue(value)
            QtGui.qApp.processEvents()
            if (not self._active or value >= self.maximum()):                
                break
        self._active = False

    def closeEvent(self, event):
        self._active = False

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.myList = ['One','Two','Three','Four','Five','Six','Seven']

        self.main_layout = QtGui.QVBoxLayout()
        self.pBars={}

        for each in self.myList:
            pb=PbWidget(total=101)
            self.main_layout.addWidget(pb)
            self.pBars[each]={'pb':pb, 'name':each, 'value': 0} 

        ok_button = QtGui.QPushButton("Distribute")
        ok_button.clicked.connect(self.OK)      
        self.main_layout.addWidget(ok_button)       

        central_widget = QtGui.QWidget()
        central_widget.setLayout(self.main_layout)
        self.setCentralWidget(central_widget)


    def internalFunc(self, myEvent, each):

        pb = self.pBars[each]['pb']

        state=True
        while state:
            if self.pBars[each]['value']>=100: state=False
            for i in range(12):
                self.pBars[each]['value']+=10
                print '\n\t ...Working on', each, self.pBars[each]['value'], '\n'
                # pb.update_bar( self.pBars[each]['value'] )
                time.sleep(0.5)

        print "\n\t ProgressBar", each, 'has reached 100%. Its value =', self.pBars[each]['value'], '\n'


    def OK(self):
        for each in self.pBars:
            self.myEvent=threading.Event()
            self.c_thread=threading.Thread(target=self.internalFunc, args=(self.myEvent, each,))
            self.c_thread.start() 


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.resize(480, 320)
    window.show()
    sys.exit(app.exec_())
alphanumeric
  • 17,967
  • 64
  • 244
  • 392
  • I see no subprocesses. Thread is not a subprocess. Is your question: "How do I show the progress made in a thread using a progress bar? How do I do it if there are multiple threads?" btw, why do you need threads here? – jfs Mar 14 '14 at 20:25
  • You are correct! An idea is to tight each thread (by mistake referred as 'sub-process') to a dedicated progress bar (there're as many progress bars as there're threads). I've already implemented the same but with multiprocessing module. It works well. But with multiprocessing I lost an ability to share the same variables/objects. That brought me to believe that I should be using threading instead of multiprocessing... since it has been mentioned threading DOES share the variable/objects. Isn't threading and multiprocessing share the same concept: just implemented differently? – alphanumeric Mar 14 '14 at 20:34
  • It looks like [XY problem](http://meta.stackexchange.com/a/66378/137096). Code-wise if it works with `multiprocessing` then it might work with `threading` (+/- a few imports and renamings e.g. `Process` -> `Thread`). The difference might be in performance (it might be slower/faster depending on your code). If your code is CPU-bound and you do not use modules that can release GIL in CPython then `threading` is not an answer because only one thread at time can run pure Python code. It doesn't apply to multiple processes such as created by `multiprocessing`. Each Python process has its own GIL. – jfs Mar 14 '14 at 20:45
  • That is, I tried and solved problem X, but I thought solution Y would work better, so instead of asking if X is the only solution I tried to solve the same problem with Y, run into trouble, and now asking about Y... :) – alphanumeric Mar 14 '14 at 21:00
  • Unfortunately I don't have much of experience with threading (as well as with multiprocessing). So I thought it would be a good chance for me to dive in to this subject deeper. It seems using multiprocessing can easily lead to a 'non-linear logic' code. But a threading module is not that much 'better' in that regard. While threading's ability to share the variables/objects is tempting it is not exactly 'plug-n-play' and requires some time to invest... which I unfortunately never have enough! – alphanumeric Mar 14 '14 at 21:05
  • `multiprocessing` should be actually easier than `multithreading` code because the variables are not shared by default and you don't need to worry about synchronization so much. [Why might threads be considered “evil”?](http://stackoverflow.com/q/1191553/4279). If you are working with Qt; you should learn about signals and slots e.g., try to reproduce [this tkinter script](https://gist.github.com/zed/4067619) or [this](https://gist.github.com/zed/9294978) using QProcess. – jfs Mar 14 '14 at 22:02

0 Answers0