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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With