Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Help with QThread



  • I'm trying to write an app that will process files in a worker thread and update a progress bar in the main window. I followed the instructions on the QThread page (I think) but when I emit the signal that starts the threads worker function my UI becomes completely unresponsive. However the progress bar updates as expected so I'm not sure what's going on.

    I setup the worker class almost exactly like the example...

    class OutputWorker : public QObject
    {
    	Q_OBJECT
    
    public:
    	OutputWorker(QObject *parent);
    	~OutputWorker();
    
    public slots:
    	void processFile(const QString &file);
    
    signals:
    	void updateProgress(const int &progress);
    };
    
    void OutputWorker::processFile(const QString &file)
    {
    	for (int i=0; i<100; i++)
    	{
    		emit updateProgress(i);
    		QThread::msleep(1000);
    	}
    }
    

    Then in my main window class I have a QThread member variable and I set it up in the constructor like so...

    OutputWorker *pWorker = new OutputWorker(this);
    pWorker->moveToThread(&m_outputThread);
    connect(&m_outputThread, &QThread::finished, pWorker, &QObject::deleteLater);
    connect(this, &MainWindow::processFile, pWorker, &OutputWorker::processFile);
    connect(pWorker, &OutputWorker::updateProgress, this, &MainWindow::on_progress_updated);
    m_outputThread.start();
    

    Then in one of my button slots I call emit like so..

    void MainWindow::on_runButton_clicked()
    {
    	emit processFile("");
    }
    

    And this is the slot for the progress bar...

    void MainWindow::on_progress_updated(int progress)
    {
    	ui.outputProgress->setValue(progress);
    }
    

    Like I said the thread runs and the progress bar updates, but the rest of the UI is completely unresponsive until it completes.

    Can anyone tell me what I'm doing wrong?



  • I figured out that if I use nullptr as the parent for the worker object, instead of this, it doesn't lock up the UI but the progress function never gets called.



  • OK I figured it out. Using nullptr was right, but the reason the signal didn't work is because the functions were slightly different. See how one is (const int &progress) and the other is just (int progress)? Once I changed them to match it worked. Not sure why it worked when I was connecting the worker to 'this'.

    Anyway, never mind, sorry for wasting your time.


  • Moderators

    @Dan203 said in Help with QThread:

    if I use nullptr as the parent for the worker object, instead of this, it doesn't lock up the UI

    Can you figure out:

    • Which object becomes the Worker Object's parent when you pass this?
    • Which object becomes the Worker Object's parent when you pass nullptr?

    See https://doc.qt.io/qt-5/qobject.html#moveToThread about moving objects which have a parent.

    my UI becomes completely unresponsive.

    Your worker object was not moved to the other thread. That means OutputWorker::processFile() was running in your GUI thread, and QThread::msleep() put the GUI thread to sleep.

    the reason the signal didn't work is because the functions were slightly different.

    Actually, that is not the core reason. Signals and slots are allowed to have different types of parameters (see https://doc.qt.io/qt-5/signalsandslots-syntaxes.html#type-checking-and-implicit-type-conversions )

    However, there is no good reason to ever use const int&. Always pass int by-value. References make sense when passing "large" objects; integers are tiny.

    Anyway, never mind, sorry for wasting your time.

    No need to apologize. This forum is a place for learning!


Log in to reply