2016-04-19 2 views
1

元のコードはここに投稿するのに大きなものです。基本的に、私はこれをやっている:Qtスロットの引数が壊れています

class MySuperClass 
{ 
    QThread thread; 
    MyClass myObject; 

    MySuperClass() 
    { 

     connect(this, &MySuperClass::onKill, &myObject, &MyClass::stop); 

     connect(&thread, &QThread::started, &myObject, &MyClass::loop); 
     connect(&myObject, &MyClass::finished, &thread, &QThread::quit); 

     myObject.moveToThread(&thread); 

     qRegisterMetaType<uint16_t>("uint32_t"); 

     connect(this, &MySuperClass::changed, &myObject, &MyClass::onChange); 
    } 

    void do() 
    { 
     emit changed(0); 
    } 
} 

'onKill-stop'シグナル/スロットはパラメータを持たず正常に動作する。ここでは問題ありません。

問題は 'changed - onChange'です。それらにはuint32_t型の1つのパラメータ(登録済み)があります。

MySuperClassのメソッドdoをメインスレッドから呼び出すと、信号が発信され、スロットonChangeが呼び出されますが、パラメータは0ではありません! これは、3043426304のような大きな数字です。

面白いのは、接続タイプをDirectConnectionに変更した場合、パラメータはゼロです。接続タイプをQueuedConnectionに変更すると、パラメータもゼロになります。どうすればいいの? AutoConnectionがQueuedかDirectですか?

私はこれに非常に困惑しています。まず第一に、スタックに割り当てられた整数型パラメータがどうしてそんなに壊れているのでしょうか?ヒープ割り当てされたものか、複数のスレッドで使用されたものなのか分かります。

私の2番目の質問は次のとおりです。この接続を正しく行うにはどうすればよいですか? connectとmoveToThreadの順序は関係しますか?

+3

奇妙なことがあります:qRegisterMetaType ( "uint32_t");それはqRegisterMetaTypeであるべきではありません。( "uint32_t"); – CppChris

+1

ChrisGがあなたの問題を指摘している可能性があります(ここでは+1)。しかし、quint32(uint32_tと互換性があります)を使用することはできますが、あらかじめ登録しておけば、登録する必要がなくなり、間違いを見つけにくくなる可能性があります。 –

+0

@ChrisG riiight、それは私の愚かなことです!愚かなコピーペーストエラー。私は、3043426304が2つの最下位ビットに0を持つことに気付かなかった。ありがとうございました!私はそれを受け入れることができるようにあなたのコメントを答えにすることができますか? (私はまだmoveToThreadの注文と接続の呼び出しに興味がありますが)。 – Amomum

答えて

2

質問1はChrisによって回答されます。

// Create the myObject object in its own thread 
QThread* myThread= new QThread(); // you can assign `this` as parent if you want... 
MyObject* myObject= new MyObject(0); // Assign no parent here (for QObject) 
QObject::connect(myThread, &QThread::started, myObject, &MyObject::run, Qt::QueuedConnection); 
myObject->moveToThread(myThread); 
myThread->start(); 

あなたはほとんどそれが正しい持っている:質問2について

これは、別々のスレッドで実行されているオブジェクトがどのようにセットアップされ...(私の周りのは初めてのことを見ていません)。私はスレッドを蹴るために "myThread-> start()"関数が欠けていると思います。オブジェクトの作成では、コンストラクターがスレッドに移動する前に実行されているため、親スレッド領域に動的割り当てが作成されることが重要です。だから、run()スロットの中に必要なオブジェクトをインスタンス化するのが最善です。

スレッドを開始した後のオブジェクトとのやりとりは、スロット/シグナル経由でなければなりません。

スレッドを開始すると、スレッドが開始され、run()スロットが呼び出されます。あなたはこのスレッドを起動するための良いです

myThread->start()

注意を呼び出す前に

接続とmoveToThreadの順序は、限り、あなたはこのすべてがそうであるように重要ではありません。スレッドをきれいに終了するのに役立つ規則がいくつかありますが、それはおそらくオフトピックになります。

+0

別の関数でスレッドを開始するので、擬似コードに入れることを忘れてしまいました。 – Amomum

+0

@Amomumああ、十分に公正:)...私はあなたが何か問題があるはずはないと思います。あなたのスレッドで何の問題がありますか? –

+0

@Amomumあなたの接続タイプ(デフォルトはauto)は、オブジェクトを別のスレッドに移動すると、信号がQt :: QueuedConnectionであることを意味します(移動前は直接接続されます)...私の例では、私が直接 –

関連する問題