Solved Signals across threads between non-child objects
-
Hey gang,
I'm developing a plugin to a piece of 3rd party software, which the 3rd party software loads as a dll. In my main application, I create an instance of the 3rd party software. The dll, by necessity, runs in a separate thread. So something like this:
mainWindow() { thirdPartyInterface(); } plugin() { //autoloaded by thirdPartyInterface() at runtime }
Due to threading requirements, plugin() is not a child object of either mainWindow() or thirdPartyInterface().
I need to send a signal across from plugin() to mainWindow(), but so far have not been able to figure out how to manage this. I attempted to set the connection type as a QueuedConnection, but I think the real issue is not designating the sender correctly.
-
You need a pointer to the object from where the signal is coming from.How you get it is up to you and plain c++ stuff (e.g. passing a pointer around, doing the connect somewhere else where both pointers are accessible, ...).
-
Two object don't need to be parent/child objects to be connected to each other. The only requirement is that both have to be derived from QObject.
-
@Christian-Ehrlicher That's great to hear. Is there a way for me to identify the sender by the QObject name? If this is just a syntax issue, I'm relieved.
-
@John-Howe said in Signals across threads between non-child objects:
Is there a way for me to identify the sender by the QObject name?
You can call sender() in the slot to get the pointer to the sender.
-
@jsulm Looks like that won't work.
QObject::connect: Cannot connect (null)::sendSignal() to MainWindow::recvSignal()
According to the documentation here: https://doc.qt.io/qt-5/qobject.html#sender the sender() function won't work when the signal comes from a thread different from the object's thread.
-
Your sender pointer is not initialized as you can see (null).
Passing the sender can also be done with e.g. a lambda. See the wiki -
@John-Howe said in Signals across threads between non-child objects:
QObject::connect: Cannot connect (null)::sendSignal() to MainWindow::recvSignal()
What are do you doing to becomes this warning?
sender()
is to be used in to slot code to be aware about which object have triggered the slot.
Butsender()
may not always be valid and his usage is not conform to Qt philosophy.
If you need sender, it is better to use lambda function. -
@KroMignon That warning comes from using sender() in my connect() code. I don't understand currently how I would use a lambda to find my sender.
-
You should not use sender() in your connect function - what should it do there?
sender() can be used in the slot to get the sender of the signal. But as we already told you it's not reliable and using a lambda should be preferred to due this. -
@Christian-Ehrlicher Gotcha, thanks for clearing that up. What do I call for my sender in the connect()?
-
@John-Howe said in Signals across threads between non-child objects:
What do I call for my sender in the connect()?
I don't understand.
-
@Christian-Ehrlicher I have to specify a pointer to the sender in the connect(), but the sender is in another thread and out of scope to the class where my slot exists. So I'm not clear how to get the signal to the slot when the QObject sender is not a child of the QObject receiver and not in the same thread.
-
You need a pointer to the object from where the signal is coming from.How you get it is up to you and plain c++ stuff (e.g. passing a pointer around, doing the connect somewhere else where both pointers are accessible, ...).
-
@John-Howe said in Signals across threads between non-child objects:
That warning comes from using sender() in my connect() code. I don't understand currently how I would use a lambda to find my sender.
First,
sender()
is set during event loop processing before signal is called.
So I don't understand why you use it inconnect()
, this does't made sense to me :(Perhaps you should begin with explaining what you want to do?