Reputation: 13
I have a Qt application that was developed using Qt Creator and the GUI tool that accompanies it. I have a main thread, TheGui
and a worker thread that is created by the main thread, WorkerThread
(called thread
).
The problem I'm having is when I create a slot in the GUI by using
public slot:
void updateTable(string str);
within the header file of the GUI and signal void sendList(string str);
within the header file of the worker thread, the slot never gets called. I connected the two using
connect(&thread, SIGNAL(sendList(string str),
this, SLOT(updateTable(string str)));
within the constructor in the GUI cpp file. I did something similar except with the slot in the worker thread and signal from the GUI and it worked fine. I know from using the debugger that the signal sendList is indeed getting called, it is just never going into it.
Any thoughts?
Upvotes: 1
Views: 3756
Reputation: 6181
Sure that connection is actually made? If there are any problems with connect call, there is usually some debugging output about it on cerr
.
Secondly, I think you have a typo - if you copied connect call from your code, then know that you have parenthesis missing around SIGNAL - should be
connect(&thread, SIGNAL(sendList(string)), this, SLOT(updateTable(string)));
Thirdly, what is that you are passing as signal/slot parameter? Is it std::string? Connections between threads must be queued connections. Queued connections can use as parameters only types declared with Q_DECLARE_METATYPE macro, and registered with qRegisterMetaType. As far as I know, Qt by default doesn't declare those for std::string
, as it prefers QString
. If you didn't add those to your code, it might be the reason for failure.
Upvotes: 1
Reputation: 29896
Because the signal and the slot are on distinct threads, the connection between them has the Qt::QueuedConnection
type. And for queued connections, Qt has to be able to save a copy of the signal parameters, to pass them later to the slot.
So, to inform Qt that the type is copyable, you have to register it with Qt's meta-object system (see QMetaType) like this:
// This macro call should be put in one of your .h files
Q_DECLARE_METATYPE(std::string)
// You should call this function before any (queued)
// signal/slot connection involving the type
qRegisterMetaType<std::string>();
The parameter name shouldn't be included in the QObject::connect
call, and the type names should be exactly the same as the ones you passed to Q_DECLARE_METATYPE
:
connect(&thread, SIGNAL(sendList(std::string), this, SLOT(updateTable(std::string)));
You can also use QString
or QByteArray
, which are already registered, instead of std::string
, since these functions are slots and signals and as such are already Qt specific.
Upvotes: 4