Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is sending signals to same object (e.g. this) in Qt an anti-pattern

Tags:

qt

I am wondering if sending a signal to the same object in Qt is considered bad-practice and an anti-pattern, or if that is just fine.

I am in a situation where I would like to do something like this:

QObject::connect (this, &MyFoo::ready,
                  this, &MyFoo::execute, 
                  Qt::ConnectionType::QueuedConnection);

Then from inside execute I would like to emit ready. The motivation for this is to avoid deep recursions. My alternative approach would be to just recursively call execute from execute.

like image 413
lanoxx Avatar asked Jun 22 '17 08:06

lanoxx


1 Answers

AFAIK, there is nothing in Qt documentation that says this is a bad practice.

I did this many times, specially in cases where my object gets notified something happened from a thread (listening a COM port, or a bluetooth connection) and a GUI update is needed:

MyObject::MyObject()
{
    connect( this, SIGNAL(dataReceived(QString)), this, SLOT(showData(QString)), Qt::ConnectionType::QueuedConnection );
}

void MyObject::receiveSomeData( QString data )
{
    // a worked thread called this function...
    // we are not in the main thread here, it's unsafe to update the GUI,
    // calling showData(data) will lead most likely lead to crashs or Qt warnings
    // so let's delay it's execution by emitting dataReceived!
    emit dataReceived( data );
}

void MyObject::showData( QString data )
{
    // now it's safe to update the GUI...we are back to main thread
    m_ui.label->setText( data );
}

Also did this kind of tricks in Qt-based class constructors where you need to wait for the widget to be actually visible before you can do some GUI operations (needing to access widget's size for instance...in your constructor, layout is not yet considered as a constraint to size the widget). Then I had to emit a signal from the widget constructor, and this signal was connected to a slot of the same widget class that would do the initialization, and Qt::ConnectionType::QueuedConnection makes the initialization function be executed after the widget actually went visible.

And there may be other situations where this is relevant...

Note: As ymoreau commented the OP, this can also be adressed by using QMetaObject::invokeMethod which most likely ends up doing the same thing.

like image 178
jpo38 Avatar answered Oct 27 '22 07:10

jpo38