Question

I'm using a library where I need to call a trigger function that starts some processing (starts a thread that does the job) and returns immediatly. Then when the processing is finished a signal is emitted.

This needs to be done periodically based on different parameters. Since other calls to the trigger function must not be done while processing I would need to queue them in some way. I thought about using a QEventLoop ("loop") but without luck so far.

Please look at this piece of code:

test::test()
    {
    connect(&timer,   SIGNAL(timeout()), this, SLOT(timerSlot()));
    connect(&timer2,  SIGNAL(timeout()), this, SLOT(timer2Slot()));
    connect(&library, SIGNAL(processingFinished()), &loop, SLOT(quit()));

    timer.setInterval(2000);
    timer.start();

    timer2.setInterval(4000);
    timer2.start();
    }

void test::timerSlot()
    {
    loop.exec();
    startProcessing(some_parameters);
    }

void test::timer2Slot()
    {
    loop.exec();
    startProcessing(some_other_parameters);
    }

The issue is that when loop.exec() is called while processing I get the message:

QEventLoop::exec: instance xxxxxx has already called exec()

What would be the right way to do what I intend?

Thanks in advance.

Was it helpful?

Solution

One simple solution is to introduce a member variable, for example, bool m_isProcessing, start processing only if m_isProcess == false, then set it to true when you start processing and reset it to false when processing is complete. Since the slots for your test QObject execute on the GUI/main thread, you don't need to worry about synchronization between timer slots and the slot that will execute when processing is finished.

If you want to keep track of events that occur during processing, you can use the same method: introduce a member variable to the test class to track the information you need.

OTHER TIPS

It seems that you are looking for Qt::QueuedConnection.

Qt::QueuedConnection 2 The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.

Therefore, you could write something like this:

connect(&timer, SIGNAL(timeout()), SLOT(timerSlot()), Qt::QueuedConnection);
connect(&timer2, SIGNAL(timeout()), SLOT(timer2Slot()), Qt::QueuedConnection);

For details, you could look into the well-known mandelbrot example how this is done in there, although it is using worker threads:

Mandelbrot Example

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top