It is possible my using the metaobject system. But be aware of the consequences.
Just take a look at this blog entry (especially the MACRO part in the comments) -> click me
I stole this part for a project some years ago and liked it (but you have to really understand what you are doing and how Qt is handling the call)
You have to define the following MACROs and extend the last part to your needs:
// HELPER MACROS (from
// Just a helper macro:
#define NO_RETURN_VALUE
// This does the real work:
#define THREAD_MAGIC(targetThread, returnValue, args) \
if(QThread::currentThread() != targetThread->thread()) \
{ \
QString slotName = __FUNCTION__; \
slotName.remove(QRegExp("^.*::")); \
bool ret = metaObject()->invokeMethod(this, \
qPrintable(slotName), Qt::QueuedConnection, \
args.count() >= 1 ? args[0] : QGenericArgument(0), \
args.count() >= 2 ? args[1] : QGenericArgument(0), \
args.count() >= 3 ? args[2] : QGenericArgument(0), \
args.count() >= 4 ? args[3] : QGenericArgument(0), \
args.count() >= 5 ? args[4] : QGenericArgument(0), \
args.count() >= 6 ? args[5] : QGenericArgument(0), \
args.count() >= 7 ? args[6] : QGenericArgument(0), \
args.count() >= 8 ? args[7] : QGenericArgument(0), \
args.count() >= 9 ? args[8] : QGenericArgument(0), \
args.count() >= 10 ? args[9] : QGenericArgument(0)); \
if(!ret) \
{ \
qFatal(qPrintable(__FUNCTION__ + \
QString(" Could not call QMetaObject::invokeMethod(). " \
"Check your argument list quantity and types."))); \
} \
return returnValue; \
}
#define MAKE_THREAD_SAFE_0(TargetThread, returnValue) \
do { \
QList<QGenericArgument> args; \
THREAD_MAGIC(TargetThread, returnValue, args); \
} while (0); \
#define THREAD_MAGIC_1(TargetThread, returnValue, ArgType1, ArgName1) \
do { \
QList<QGenericArgument> args = QList<QGenericArgument>() << \
Q_ARG(ArgType1, ArgName1); \
THREAD_MAGIC(TargetThread, returnValue, args); \
} while (0);
\
#define THREAD_MAGIC_2(TargetThread, returnValue, ArgType1, ArgName1, ArgType2, ArgName2) \
do { \
QList<QGenericArgument> args = QList<QGenericArgument>() << \
Q_ARG(ArgType1, ArgName1) << \
Q_ARG(ArgType2, ArgName2); \
THREAD_MAGIC(TargetThread, returnValue, args); \
} while (0);
Now you have to implement your functions as e.g.
void ThreadClass::fn(const QString& user_, const QString& pwd_)
{
THREAD_MAGIC_2(this, NO_RETURN_VALUE, QString, user_, QString, pwd_);
// ... implementation of the function
}
As i already said: It was not my idea - credit goes to Dave Smith.