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?
解决方案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<: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.