18

私は次のコードを持っています:

class A : public QObject
{
    Q_OBJECT
public:
    A() : QObject()
    {
         moveToThread(&t);
         t.start();
    }
    ~A()
    {
         t.quit();
         t.wait();
    }

    void doSomething()
    { 
         QMetaObject::invokeMethod(this,"doSomethingSlot");
    }
public slots:
    void doSomethingSlot()
    {
         //do something
         emit ready();
    }
signals:
    void ready();
private:
    QThread t;
}

なぜそれからdoSomething経由で呼び出さなければならないのかという質問QMetaObject::invokeMethod。接続型に何かがあることは知っています。誰かがボンネットの下にあるものを説明できますか?

4

2 に答える 2

33

を指定していないためQt::ConnectionType、メソッドは として呼び出されますQt::AutoConnection。つまり、オブジェクトのスレッド アフィニティが現在のスレッドに対するものである場合は (通常の関数呼び出しのように) 同期的に呼び出され、それ以外の場合は非同期的に呼び出されます。「非同期的に」とは、 aQEventが構築されてメッセージ キューにプッシュされ、イベント ループが到達したときに処理されることを意味します。

受信者オブジェクトが別のスレッドにある可能性がある場合に使用する理由QMetaObject::invokeMethodは、別のスレッドのオブジェクトでスロットを直接呼び出そうとすると、スレッドセーフでないデータにアクセスまたは変更すると、破損または悪化する可能性があるためです。

于 2012-12-19T08:56:13.497 に答える
29

私はこのトリックが好きです:

void A:doSomethingSlot()
{
     if (thread()!=QThread::currentThread()) {
         QMetaObject::invokeMethod(this,"doSomethingSlot", Qt::QueuedConnection);
         return;
     }
     // this is done always in same thread
     ...
     emit ready();
}
于 2012-12-19T09:27:27.470 に答える