<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Talking to Qt Threads</title>
	<atom:link href="http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/feed/" rel="self" type="application/rss+xml" />
	<link>http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/</link>
	<description>Your blog is probably better than mine.</description>
	<lastBuildDate>Tue, 07 Sep 2010 02:05:02 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	<item>
		<title>By: Dave</title>
		<link>http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/comment-page-1/#comment-103256</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Sun, 20 Jun 2010 03:08:46 +0000</pubDate>
		<guid isPermaLink="false">http://thesmithfam.org/blog/?p=609#comment-103256</guid>
		<description>Well, it turns out I was wrong with this article. You don&#039;t actually have to subclass QThread. You can just *use* one, as noted here:

http://blog.exys.org/entries/2010/QThread_affinity.html

Here&#039;s a revised version:

main.cpp:
&lt;pre&gt;
#include &lt;qthread&gt;
#include &lt;qtdebug&gt;
#include &lt;qcoreapplication&gt;

class MyObject : public QObject
{
    Q_OBJECT

    public:
        MyObject() : QObject(NULL)
        {
            moveToThread(&amp;_thread);
            _thread.start();
        }

    public slots:
        void safelyDoSomething()
        {
            if(QThread::currentThread() != &amp;_thread)
            {
                qDebug() &lt; &lt; __FUNCTION__ &lt;&lt; &quot;Wrong thread&quot;;
                QMetaObject::invokeMethod(this, &quot;safelyDoSomething&quot;,
                        Qt::QueuedConnection);
            }
            else
            {
                qDebug() &lt;&lt; __FUNCTION__ &lt;&lt; &quot;Right thread&quot;;
            }
        }

    private:
        QThread _thread;
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    MyObject object;
    object.safelyDoSomething();

    return app.exec();
}

#include &quot;main.moc&quot;
&lt;/pre&gt;&lt;/qcoreapplication&gt;&lt;/qtdebug&gt;&lt;/qthread&gt;&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Well, it turns out I was wrong with this article. You don&#8217;t actually have to subclass QThread. You can just *use* one, as noted here:</p>
<p><a href="http://blog.exys.org/entries/2010/QThread_affinity.html" rel="nofollow">http://blog.exys.org/entries/2010/QThread_affinity.html</a></p>
<p>Here&#8217;s a revised version:</p>
<p>main.cpp:</p>
<pre>
#include <qthread>
#include <qtdebug>
#include <qcoreapplication>

class MyObject : public QObject
{
    Q_OBJECT

    public:
        MyObject() : QObject(NULL)
        {
            moveToThread(&#038;_thread);
            _thread.start();
        }

    public slots:
        void safelyDoSomething()
        {
            if(QThread::currentThread() != &#038;_thread)
            {
                qDebug() < < __FUNCTION__ << "Wrong thread";
                QMetaObject::invokeMethod(this, "safelyDoSomething",
                        Qt::QueuedConnection);
            }
            else
            {
                qDebug() << __FUNCTION__ << "Right thread";
            }
        }

    private:
        QThread _thread;
};

int main(int argc, char **argv)
{
    QCoreApplication app(argc, argv);

    MyObject object;
    object.safelyDoSomething();

    return app.exec();
}

#include "main.moc"
</pre>
<p></qcoreapplication></qtdebug></qthread></pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/comment-page-1/#comment-102151</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Fri, 14 May 2010 03:12:52 +0000</pubDate>
		<guid isPermaLink="false">http://thesmithfam.org/blog/?p=609#comment-102151</guid>
		<description>RJ: Here&#039;s an example macro that you can place within slots to make them thread safe:

&lt;style&gt;
pre {
font-weight: normal;
font-size: 9px;
}
&lt;/style&gt;

&lt;pre&gt;
// Just a helper macro:
#define NO_RETURN_VALUE

// This does the real work:
#define THREAD_MAGIC(targetThread, returnValue, args)     \
    if(QThread::currentThread() != targetThread)                     \
    {                                                                \
        QString slotName = __FUNCTION__;                             \
        slotName.remove(QRegExp(&quot;^.*::&quot;));                           \
        bool ret = metaObject()-&gt;invokeMethod(this,                  \
                qPrintable(slotName), Qt::QueuedConnection,          \
                args.count() &gt;=  1 ? args[0] : QGenericArgument(0),  \
                args.count() &gt;=  2 ? args[1] : QGenericArgument(0),  \
                args.count() &gt;=  3 ? args[2] : QGenericArgument(0),  \
                args.count() &gt;=  4 ? args[3] : QGenericArgument(0),  \
                args.count() &gt;=  5 ? args[4] : QGenericArgument(0),  \
                args.count() &gt;=  6 ? args[5] : QGenericArgument(0),  \
                args.count() &gt;=  7 ? args[6] : QGenericArgument(0),  \
                args.count() &gt;=  8 ? args[7] : QGenericArgument(0),  \
                args.count() &gt;=  9 ? args[8] : QGenericArgument(0),  \
                args.count() &gt;= 10 ? args[9] : QGenericArgument(0)); \
        if(!ret)                                                     \
        {                                                            \
            qFatal(qPrintable(__FUNCTION__ +                         \
              QString(&quot; Could not call QMetaObject::invokeMethod(). &quot; \
              &quot;Check your argument list quantity and types.&quot;)));     \
        }                                                            \
        return returnValue;                                          \
     }        

#define MAKE_THREAD_SAFE_0(TargetThread, returnValue)                \
        do {                                                         \
        QList&lt;QGenericArgument&gt; args;                                \
        THREAD_ME_LIKE_A_NEEDLE(TargetThread, returnValue, args);    \
        } while (0);                                                  \


#define THREAD_MAGIC_1(TargetThread, returnValue, ArgType1, ArgName1)         \
        do {                                                         \
        QList&lt;QGenericArgument&gt; args = QList&lt;QGenericArgument&gt;() &lt;&lt;  \
            Q_ARG(ArgType1, ArgName1);                               \
        THREAD_MAGIC(TargetThread, returnValue, args);    \
        } while (0);              
                                                       \

#define THREAD_MAGIC_2(TargetThread, returnValue, ArgType1, ArgName1, ArgType2, ArgName2) \
        do {                                                         \
        QList&lt;QGenericArgument&gt; args = QList&lt;QGenericArgument&gt;() &lt;  \
            Q_ARG(ArgType1, ArgName1) &lt; &lt;                             \
            Q_ARG(ArgType2, ArgName2);                               \
        THREAD_MAGIC(TargetThread, returnValue, args);    \
        } while (0);                                                  \


&lt;/pre&gt;

And now the usage in one of your slots:
&lt;/pre&gt;&lt;pre&gt;
void MyThread::mySlot(const QString &amp;name, int count)
{
   THREAD_MAGIC_2(this, NO_RETURN_VALUE, QString, name, int, count);

  // You are now thread safe
}
&lt;/pre&gt;

Notice you can only use this with slots that have between 0 and 10 arguments, which is actually a limitation of Qt&#039;s signal/slot system (if I recall correctly).

Happy thread hacking!</description>
		<content:encoded><![CDATA[<p>RJ: Here&#8217;s an example macro that you can place within slots to make them thread safe:</p>
<style>
pre {
font-weight: normal;
font-size: 9px;
}
</style>
<pre>
// Just a helper macro:
#define NO_RETURN_VALUE

// This does the real work:
#define THREAD_MAGIC(targetThread, returnValue, args)     \
    if(QThread::currentThread() != targetThread)                     \
    {                                                                \
        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&lt;QGenericArgument> args;                                \
        THREAD_ME_LIKE_A_NEEDLE(TargetThread, returnValue, args);    \
        } while (0);                                                  \

#define THREAD_MAGIC_1(TargetThread, returnValue, ArgType1, ArgName1)         \
        do {                                                         \
        QList&lt;QGenericArgument> args = QList&lt;QGenericArgument>() &lt;&lt;  \
            Q_ARG(ArgType1, ArgName1);                               \
        THREAD_MAGIC(TargetThread, returnValue, args);    \
        } while (0);
                                                       \

#define THREAD_MAGIC_2(TargetThread, returnValue, ArgType1, ArgName1, ArgType2, ArgName2) \
        do {                                                         \
        QList&lt;QGenericArgument> args = QList&lt;QGenericArgument>() &lt;  \
            Q_ARG(ArgType1, ArgName1) < <                             \
            Q_ARG(ArgType2, ArgName2);                               \
        THREAD_MAGIC(TargetThread, returnValue, args);    \
        } while (0);                                                  \
</pre>
<p>And now the usage in one of your slots:
</pre>
<pre>
void MyThread::mySlot(const QString &#038;name, int count)
{
   THREAD_MAGIC_2(this, NO_RETURN_VALUE, QString, name, int, count);

  // You are now thread safe
}
</pre>
<p>Notice you can only use this with slots that have between 0 and 10 arguments, which is actually a limitation of Qt&#8217;s signal/slot system (if I recall correctly).</p>
<p>Happy thread hacking!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Dave</title>
		<link>http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/comment-page-1/#comment-102142</link>
		<dc:creator>Dave</dc:creator>
		<pubDate>Thu, 13 May 2010 22:49:15 +0000</pubDate>
		<guid isPermaLink="false">http://thesmithfam.org/blog/?p=609#comment-102142</guid>
		<description>RJ: Great question. I actually wrote a macro a while back. I&#039;ll post a comment here when I get home tonight to explain the missing parts. Maybe I&#039;ll write a new blog post just about the macro method.</description>
		<content:encoded><![CDATA[<p>RJ: Great question. I actually wrote a macro a while back. I&#8217;ll post a comment here when I get home tonight to explain the missing parts. Maybe I&#8217;ll write a new blog post just about the macro method.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: RJ</title>
		<link>http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/comment-page-1/#comment-102141</link>
		<dc:creator>RJ</dc:creator>
		<pubDate>Thu, 13 May 2010 22:41:00 +0000</pubDate>
		<guid isPermaLink="false">http://thesmithfam.org/blog/?p=609#comment-102141</guid>
		<description>I want to write a macro for this QMetaObject::invoke trick, since I&#039;m using it in a few places, but I want it to work in slots that also have parameters.

These are non variadic methods tho, don&#039;t know how to get a list of pointers to passed arguments.

Using the following, i can get a list of parameter type strings (needed for QGenericArgument), but i&#039;m missing the param values. Any ideas?

    QString qfi( Q_FUNC_INFO );
    Q_ASSERT( qfi.startsWith(&quot;void &quot;) );
    int methid = metaObject()-&gt;indexOfSlot( qfi.remove(0, qfi.indexOf(&quot;::&quot;)+2 ) );
    Q_ASSERT( methid != -1 ); // must be a slot, not just a method
    QMetaMethod mm = metaObject()-&gt;method( methid );


    qDebug()&lt;&lt; mm.signature()
            &lt;&lt; &quot;index:&quot; &lt;&lt; methid
            &lt;&lt; &quot;ParamNames: &quot; &lt;&lt; mm.parameterNames()
            &lt;&lt; &quot;paramtypes: &quot; &lt;&lt; mm.parameterTypes();</description>
		<content:encoded><![CDATA[<p>I want to write a macro for this QMetaObject::invoke trick, since I&#8217;m using it in a few places, but I want it to work in slots that also have parameters.</p>
<p>These are non variadic methods tho, don&#8217;t know how to get a list of pointers to passed arguments.</p>
<p>Using the following, i can get a list of parameter type strings (needed for QGenericArgument), but i&#8217;m missing the param values. Any ideas?</p>
<p>    QString qfi( Q_FUNC_INFO );<br />
    Q_ASSERT( qfi.startsWith(&#8220;void &#8220;) );<br />
    int methid = metaObject()-&gt;indexOfSlot( qfi.remove(0, qfi.indexOf(&#8220;::&#8221;)+2 ) );<br />
    Q_ASSERT( methid != -1 ); // must be a slot, not just a method<br />
    QMetaMethod mm = metaObject()-&gt;method( methid );</p>
<p>    qDebug()&lt;&lt; mm.signature()<br />
            &lt;&lt; &quot;index:&quot; &lt;&lt; methid<br />
            &lt;&lt; &quot;ParamNames: &quot; &lt;&lt; mm.parameterNames()<br />
            &lt;&lt; &quot;paramtypes: &quot; &lt;&lt; mm.parameterTypes();</p>
]]></content:encoded>
	</item>
</channel>
</rss>
