Can someone please explain how to use threading in my script?
<p>I have been playing around with python for about three months and a few days ago I was needing to do some menial task (folder creation) and I actually made a script to do it.</p>

<p>Out of pure perfectionism I wanted to add a progress bar but when I run the script, it hangs, then says complete once it's finished. I would like to see the progress bar going to 100% and not hanging. I have read that I need to use python threading to do this but I am really confused as to how to implement it but also understand it.</p>

<p>I have copied the section of the code that I would theoretically need to thread. As you can see I am using a QT Designer UI and Progress Bar.</p>

<p>Also the spacing is not an issue. This is my first time posting on Stack Overflow so forgive me if I messed up the code spacing here.</p>

<p>Thank you very much for any light you can shed on this for me.</p>

<pre><code>class ShotCreator(QtGui.QDialog):
    def __init__(self, *args):
        ui = 'ShotCreator_UI.ui'
        QtGui.QWidget.__init__(self, *args)
        loadUi(ui, self)
        self.show()      

        #Slots

        self.connect(self.browseLocation_btn, QtCore.SIGNAL("clicked()"), self.openBrowse)
        self.connect(self.create_btn, QtCore.SIGNAL("clicked()"), self.makeDir)
        self.progressBar.setValue(0)




    def makeDir(self):
        #Get data
        departments = self.queryValues()
        shots = self.fullShotAmount()
        proj = self.projName()

        #Converting proj to string
        proj = str(proj)

        #Converting dirLoc to string
        dirLoc = self.browseLocation.text()
        dirLoc = str(dirLoc)

        if dirLoc == "":
            msgBox = QtGui.QMessageBox()
            msgBox.setIcon(QMessageBox.Warning)
            msgBox.setWindowTitle("Oops - Directory Location")
            msgBox.setText("Please give a directory location")
            msgBox.exec_()


    #Creating shot numbers
        shot = 0
        for s in shots:
            shot = shot + 5
            sShot = ("00" + str(shot))

            if not os.path.exists(sShot):

                #Create shot folders
                os.mkdir(sShot)

                self.progressBar.setValue((int(s) / int(len(shots))* 100))

    self.progressBar.setValue(100)
</code></pre>

<p>It's usually best to move your business logic out of the GUI code and place it in a separate module that isn't dependent on Qt.  That makes it executing it in another thread easier.</p>

<p>For functions that I want progress feedback on, I usually turn them into generators.</p>

<pre><code>from __future__ import division

def makeDir(dirloc, shots):
    cnt = len(shots)
    #Creating shot numbers
    shot = 0
    for i, s in enumerate(shots):
        shot = shot + 5
        sShot = ("00" + str(shot))

        if not os.path.exists(sShot):

            #Create shot folders
            os.mkdir(sShot)

        yield int((i + 1) / cnt * 100)
</code></pre>

<p>You create a worker object in another thread that will execute this business logic and report progress back to the main GUI thread using Signals, so that the progress bar can update</p>

<pre><code>class Worker(QObject):

    progress_updated = pyqtSignal(int)
    finished = pyqtSignal()

    @pyqtSlot(object, object)
    def makeDir(self, dirloc, shots):
        for progress in makeDir(dirloc, shots):
            self.progress_updated.emit(progress)
        self.finished.emit()
</code></pre>

<p>Then add this worker to your GUI class and connect to the signals</p>

<pre><code>class ShotCreator(QtGui.QDialog):

    start_makedirs = pyqtSignal(object, object)

    def __init__(self, *args):
        ui = 'ShotCreator_UI.ui'
        QtGui.QWidget.__init__(self, *args)
        loadUi(ui, self)
        self.show()      

        #Slots

        self.connect(self.browseLocation_btn, QtCore.SIGNAL("clicked()"), self.openBrowse)
        self.connect(self.create_btn, QtCore.SIGNAL("clicked()"), self.makeDir)
        self.progressBar.setValue(0)

        self.thread = QThread(self)
        self.worker = Worker(self)
        self.worker.progress_updated.connect(self.update_progress)
        self.worker.finished.connect(self.worker_finished)
        self.start_makedirs.connect(self.worker.makeDir)
        self.worker.moveToThread(self.thread)
        self.thread.start()

    def makeDir(self):
        # gather information from gui
        dirloc = ''
        shots = []
        ...
        self.start_makedirs.emit(dirloc, shots)

    @pyqtSlot(int)
    def update_progress(self, progress):
        self.progressBar.setValue(progress)

    @pyqtSlot()
    def worker_finished(self):
        self.progressBar.setValue(100)
</code></pre>

python multithreading for-loop pyqt