1
votes

I know that this is next question about connect signal/slot mechanism between threads. I wrote working Worker application.

Main problem

I have worker class that has been moved to another thread. Second part of application is GUI interface with button. When I click button thread starts:

void MainWindow::startStopThreadA()
{
    ...
    else
    {
        threadA = new QThread;
        workerA = new WorkerObject;
        workerA->setMessage("Thread A running");
        workerA->moveToThread(threadA);

        connect(threadA, SIGNAL(started()), workerA, SLOT(process()), Qt::QueuedConnection);
        connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
        connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
        connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
        //Connect signal from thread with slot from MainWindow
        connect(workerA, SIGNAL(printMessage(QString)), this, SLOT(printMessage(QString)), Qt::QueuedConnection);

        threadA->start();
        ui->threadAButton->setText("Stop A");
    }
}

When thread starts then emits signal:

void WorkerObject::process(void)
{
    //Infinity thread loop
    forever
    {
        //Exit loop part
        mutex.lock();
        if(m_stop)
        {
            m_stop = false;
            mutex.unlock();
            break;
        }
        mutex.unlock();

        //Hold/unhold loop part
        mutex.lock();
        if(!m_hold)
        {
            mutex.unlock();
            //Here signal is emited
            emit printMessage(messageStr);          //That not works
            //qDebug() << "Thread A test message."; //That works properly
        }
        mutex.unlock();
    }
    emit finished();
}

In main GUI thread I have timer for show that GUI thread works. So qDebug() works fine and prints messages from my thread. Also timer from GUI thread works fine and prints message inside textEdit GUI field.

Now when printMessage signal is emited, GUI thread executes slot method:

void MainWindow::printMessage(QString str)
{
    ui->textEdit->append(str);
}

And this is most important part of my problem:

When signal printMessage from workerA object is connected with GUI slot printMessage with Qt::QueuedConnection my application hangs up. There is no possible to click something button or even exit app.

When signal/slot are connected with Qt::BlockingQueuedConnection everything works fine. Messages are emitted and received between threads and also GUI timer works fine.

So my question is why connection Qt::QueuedConnection causes that app freezes ?

1
That is strange, normally it should work. Can you break/pause your program using a debugger and check what the main/GUI thread is doing? You can try to perform a QThread::sleep inside your forever loop (f.e. 1 second) to check if it solves your problem. - m7913d
@m7913d, Yes, that really helped me. I used QThread::msleep(2) for example and that really working now. Maby signal was emitted too frequently. @G.M., is definied in worker as QString messageStr and value is assigned in worker's ctor. In main GUI is only read from emitted signal. - drewpol
Does this solves your problem? If so, you may consider writing an answer yourself. If not, please clarify further. - m7913d

1 Answers

0
votes

I figured out this problem with @m7913d help.

You can try to perform a QThread::sleep inside your forever loop (f.e. 1 second) to check if it solves your problem.

So worker's thread emitted signal too frequently. Adding QThread::msleep(5) after emitted signal really helped. There ` also need to be included.