Why I need to call processEvents() to get QThread working?

python
qt

#1

Here is my code for listing all sub-directories of a directory. I’m using it to understand QThread and signal and slots in pyside.
The problem is when I’m not using Qtcore.QApplication.processEvents() in scan() function of Main class, the code is not working. Is the event loop not already running?

import sys
import os
import time
from PySide import QtGui, QtCore

class Scanner(QtCore.QObject):
    folderFound = QtCore.Signal(str)
    done = QtCore.Signal()
    def __init__(self, path):
        super(Scanner, self).__init__()
        self.path = path

    @QtCore.Slot()
    def scan(self):
        for folder in os.listdir(self.path):
            time.sleep(1)
            self.folderFound.emit(folder)
            
	
class Main(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.resize(420,130)
        self.setWindowTitle('Threads')
        self.lyt = QtGui.QVBoxLayout()
        self.setLayout(self.lyt)

        self.topLyt = QtGui.QHBoxLayout()
        self.lyt.addLayout(self.topLyt)
        self.scanBtn = QtGui.QPushButton('Scan')
        self.scanBtn.clicked.connect(self.scan)
        self.clearBtn = QtGui.QPushButton('Clear')
        self.topLyt.addWidget(self.scanBtn)
        self.topLyt.addWidget(self.clearBtn)

        self.folders = list()

        self.show()

    def scan(self):
        self.th = QtCore.QThread()
        scanner = Scanner(r"D:\\")
        scanner.moveToThread(self.th)

        scanner.folderFound.connect(self.addFolder)
        scanner.done.connect(scanner.deleteLater)
        scanner.done.connect(self.quit)

        self.th.started.connect(scanner.scan)
        self.th.start()
        
        QtCore.QApplication.processEvents()

    @QtCore.Slot()
    def addFolder(self, folder):
        lbl = QtGui.QLabel(folder)
        self.folders.append(lbl)

        self.lyt.addWidget(lbl)

    @QtCore.Slot()
    def quit(self):
        self.th.quit()
        self.th.wait()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    main = Main()    
    app.exec_()

#2

Could you use QFileSystemWatcher for this? I might handle most of your heavy lifting.


#3

Actually my concern is about why do I need to call processesEvents() after self.th.start(). The operation I need to do in the thread is quite complex, listing of sub-directories in this code is just for testing purpose. By the way I didn’t know about QFileSystemWatcher. Thanks for that.