Maybe a bit offtopic, but next pattern may help you (when you need only one slot call per several operations). For example, when you have a lot of unpredictable data changes and you need to update a view.
class SlotProxy : public QObject
{
Q_OBJECT
signals:
void triggered();
public:
explicit SlotProxy( QObject *parent = nullptr );
void trigger();
private:
void onTimeout();
private:
QPointer<QTimer> _timer;
};
SlotProxy::SlotProxy( QObject *parent = nullptr )
: _timer{ new QTimer{ this } }
{
_timer->setInterval( 0 );
_timer->setSingleShot( true );
connect( _timer, &QTimer::timeout, this, &SlotProxy::onTimeout );
}
void SlotProxy::trigger()
{
_timer->start( 0 ); // May be not zero;
}
void SlotProxy::onTimeout()
{
emit triggered();
}
Usage:
class MyForm : public QWidget
{
/*...*/
void updateGui();
};
class Worker : public QObject
{
/*...*/
signals:
void updateRequest();
public:
explicit Worker( QObject *parent = nullptr );
private:
void heavyTask();
private:
SlotProxy _proxy;
};
Worker::Worker( QObject *parent )
: QObject{ parent }
{
connect( _proxy, &SlotProxy::triggered, this, &Worker::updateRequest );
}
void Worker::heavyTask()
{
for ( auto i = 0; i < 1000; i++ )
{
/*...*/
_proxy.trigger();
}
}
MyForm form;
Worker worker;
QObject::connect( &worker, &Worker::updateRequest, &form, &MyForm::updateGui );
worker.heavyTask();
// here you will have only 1 slot MyForm::updateGui in queue
Subject to improve. You may call _timer->start( 100 );
with non-zero timeout for better latency, but you need to somehow force emitting a signal periodically. It will do a code a bit more complex, please write a comment if you need help.