Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QThread Signal not processed when ProgressDialog is Modal
Forum Updated to NodeBB v4.3 + New Features

QThread Signal not processed when ProgressDialog is Modal

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 717 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • parisisalP Offline
    parisisalP Offline
    parisisal
    wrote on last edited by
    #1

    Hi,
    I have some job to do, and i want split this job in 4 threads.
    Every thread must send a signal containing the progress in order to update a progress dialog.

    I've a simple Worker class :

    Worker::Worker(int _index)
    {
    	index = _index;
    }
    
    Worker::~Worker()
    {
    }
    
    void Worker::process() { 
    	qDebug() << "Job Start" << index;
    	for (long i = 0; i < 25; i++)
    	{
    		for (long j = 0; j < 2500000; j++)
    		{
    		      int t = sin(j) + cos(j) + tan(j) + j * cos(sin(j));
    		}
    		emit progress(index, 1);
    	}
    	qDebug() << "I ended my job" << index;
    	emit finished();
    	emit finish(index);
    }
    

    then, in the main window I call :

    QtThreadTest::QtThreadTest(QWidget *parent)
    	: QMainWindow(parent)
    {
    	ui.setupUi(this);
    	
    	checkCounter = 0;
    
    	for (int i = 0; i < 4; i++)
    	{
    		threadList.append(new QThread());
    		workerList.append(new Worker(i));
    	}
    
    	for (int i = 0; i < 4; i++)
    	{
    		QThread *thread = threadList.at(i);
    		Worker  *worker = workerList.at(i);
    		worker->moveToThread(thread);
    		QObject::connect(worker, SIGNAL(progress(int, int)), this, SLOT(updateProgressDialog(int, int)));
    		QObject::connect(thread, SIGNAL(started()),  worker, SLOT(process()));
    		QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
    		QObject::connect(worker, SIGNAL(finish(int)), this, SLOT(manageFinish(int)));
    		QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    		checkCounter++;
    	}
    	progressDialog.setModal(true);
    	progressDialog.show();
    
    	for (int i = 0; i < 4; i++)
    	{
    		QThread *thread = threadList.at(i);
    		thread->start();
    	}
    
    }
    
    void QtThreadTest::updateProgressDialog(int index, int val)
    {
    	qDebug() << "Received Progress" << val << "from Thread" << index;
    	mutex2.lock();
    	int old = progressDialog.value();
    	progressDialog.setValue(old+val);
    	mutex2.unlock();
    }
    
    void QtThreadTest::manageFinish(int index)
    {
    	mutex.lock();
    	checkCounter--;
    	if (checkCounter == 0)
    	{
    		qDebug() << "ALL FINISHED" << index;
    		progressDialog.close();
    	}
    	mutex.unlock();
    }
    

    Everytime I run this program I always get an "incomplete" progress dialog (sometimes shows 5%, sometimes 7%, sometimes 10%)
    this is the output :

    Job Start 0
    Job Start 1
    Job Start 3
    Job Start 2
    Received Progress 1 from Thread 3
    Received Progress 1 from Thread 1
    Received Progress 1 from Thread 2
    Received Progress 1 from Thread 0
    Received Progress 1 from Thread 1
    Received Progress 1 from Thread 3
    Received Progress 1 from Thread 2
    Received Progress 1 from Thread 0
    Received Progress 1 from Thread 1
    Received Progress 1 from Thread 3
    Received Progress 1 from Thread 0
    Received Progress 1 from Thread 2
    I ended my job 0
    I ended my job 1
    I ended my job 2
    I ended my job 3
    

    The mainwindows misses a lot of signals emitted from the threads:

    • a lot of progress(int,int) singlas
    • 4x finished() signals
    • 4x finish(int) signals
      why ?

    If I set the progress dialog not modal -> progressDialog.setModal(false) I have the correct behavior :

    Job Start 0
    Job Start 1
    Job Start 3
    Job Start 2
    Received Progress 1 from Thread 1
    Received Progress 1 from Thread 3
    Received Progress 1 from Thread 2
    ...
    ... 
    ...
    ...
    Received Progress 1 from Thread 0
    I ended my job 1
    Received Progress 1 from Thread 1
    Il thread 0x1f60 è terminato con il codice 0 (0x0).
    I ended my job 3
    Received Progress 1 from Thread 3
    Il thread 0x3f74 è terminato con il codice 0 (0x0).
    I ended my job 2
    Received Progress 1 from Thread 2
    Il thread 0x2154 è terminato con il codice 0 (0x0).
    I ended my job 0
    Received Progress 1 from Thread 0
    ALL FINISHED 0
    Il thread 0x13cc è terminato con il codice 0 (0x0).
    

    What is the mistake?
    A bad thread managing ?
    A bad signals/slots managing ?
    both ?

    Thank you,
    Salvo

    1 Reply Last reply
    0
    • B Offline
      B Offline
      bludger
      wrote on last edited by
      #2

      @parisisal said in QThread Signal not processed when ProgressDialog is Modal:

      progressDialog.setModal(true);
      progressDialog.show();

      for (int i = 0; i < 4; i++)
      {
      QThread *thread = threadList.at(i);
      thread->start();
      }

      Since .show() will only return after the user closes the dialog in case it is set as modal. Your threads will be started afterwards. I'll suggest to change your code order:

          for (int i = 0; i < 4; i++)
          {
             QThread *thread = threadList.at(i);
              thread->start();
          }
          progressDialog.setModal(true);
          progressDialog.show();
      

      Furthermore I'd like to suggest to take a look at the QThreadPool class. It will perfectly suits your needs in this case.

      1 Reply Last reply
      1
      • parisisalP Offline
        parisisalP Offline
        parisisal
        wrote on last edited by
        #3

        Thank you, I'll try.
        I have a question.
        If .show() is blocking (returns after the user closes the dialog), why the Threads starts ?
        In the output I see :

        Job Start 0
        Job Start 1
        Job Start 3
        Job Start 2
        Received Progress 1 from Thread 3
        Received Progress 1 from Thread 1
        Received Progress 1 from Thread 2
        Received Progress 1 from Thread 0
        Received Progress 1 from Thread 1
        Received Progress 1 from Thread 3
        Received Progress 1 from Thread 2
        Received Progress 1 from Thread 0
        Received Progress 1 from Thread 1
        Received Progress 1 from Thread 3
        Received Progress 1 from Thread 0
        Received Progress 1 from Thread 2
        I ended my job 0
        I ended my job 1
        I ended my job 2
        I ended my job 3
        

        The job starts, do the work, and ends. But the signals/slots doesn't work.

        J.HilkJ 1 Reply Last reply
        0
        • parisisalP parisisal

          Thank you, I'll try.
          I have a question.
          If .show() is blocking (returns after the user closes the dialog), why the Threads starts ?
          In the output I see :

          Job Start 0
          Job Start 1
          Job Start 3
          Job Start 2
          Received Progress 1 from Thread 3
          Received Progress 1 from Thread 1
          Received Progress 1 from Thread 2
          Received Progress 1 from Thread 0
          Received Progress 1 from Thread 1
          Received Progress 1 from Thread 3
          Received Progress 1 from Thread 2
          Received Progress 1 from Thread 0
          Received Progress 1 from Thread 1
          Received Progress 1 from Thread 3
          Received Progress 1 from Thread 0
          Received Progress 1 from Thread 2
          I ended my job 0
          I ended my job 1
          I ended my job 2
          I ended my job 3
          

          The job starts, do the work, and ends. But the signals/slots doesn't work.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by J.Hilk
          #4

          hi @parisisal

          I think the issue is with progressDialog, you should set the maximum, (the default is 100 but just in case) and you should set the minimum, as that resets the current value to 0.

          that said, from the docu it says:

          Warning: If the progress dialog is modal (see QProgressDialog::QProgressDialog()), setValue() calls QApplication::processEvents(), so take care that this does not cause undesirable re-entrancy in your code. For example, don't use a QProgressDialog inside a paintEvent()!
          

          that means, when one signal is invoking the slot, all queued signals will be processed, and because the set value function is mutex locked, they will exit the slot without modifiying the value.


          you could try setting a member int and increase that, and print it to the console, to see if it reaches 100 or not


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved