2

簡単な質問: QObject を QThread から切り離してメインスレッドに移動することは可能ですか?

次のコードを使用します。

QThread *thread = new QThread();

MyObject *object = new MyObject();

object->moveToThread(thread);

thread->start();

MyObjectそして、インスタンスをメインスレッドに移動したい後のどこか。

object->moveToThread(QApplication::instance()->thread());

次のエラーがあります: QObject::moveToThread: Current thread (0x00000001) is not the object's thread (0x00000002). Cannot move to target thread (0x00000003)

ありがとう

4

1 に答える 1

3

公式ドキュメントが言うように、moveToThread関数は別のスレッドからオブジェクトを「プル」することはできず、オブジェクトを別のスレッドに「プッシュ」します。

そのため、オブジェクトのスレッド アフィニティを変更する場合は、現在のオブジェクトのスレッドで行う必要があります。

簡単な例を追加しました。

Workerクラスは次のとおりです。

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0);
signals:
    void done();

public slots:
    void doWork();
    void checkThread();

private:
    bool isMainThread();
};

Worker::Worker(QObject *parent) :
    QObject(parent)
{
    qDebug() << __PRETTY_FUNCTION__ 
             << QThread::currentThread() 
             << isMainThread();
}

void Worker::doWork()
{
    qDebug() << __PRETTY_FUNCTION__ 
             << QThread::currentThread() 
             << isMainThread();

    qDebug() << __PRETTY_FUNCTION__ << "Work is done";
    moveToThread(qApp->thread());
    emit done();
}

void Worker::checkThread()
{
    qDebug() << __PRETTY_FUNCTION__ 
             << QThread::currentThread() 
             << isMainThread();
}

bool Worker::isMainThread()
{
    return QThread::currentThread() == qApp->thread();
}

Workerオブジェクト、オブジェクトを作成し、QThreadそれらを相互に接続します。

QThread *thread = new QThread;
Worker *worker = new Worker;
worker->moveToThread(thread);

QObject::connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
QObject::connect(worker, SIGNAL(done()), thread, SLOT(quit()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(checkThread()));
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

thread->start();

それが、アプリケーションの出力で得られたものです。

Worker::Worker(QObject*) QThread(0x1034680) true 
void Worker::doWork() QThread(0x1224970) false 
void Worker::doWork() Work is done 
void Worker::checkThread() QThread(0x1034680) true 

Workerオブジェクトはメイン アプリケーション スレッドで作成され、新しいスレッドでその作業を行います。ジョブが完了すると、done()シグナルを送信し、メイン スレッドに戻ります。Workerスレッドが終了したら、オブジェクトが本当にメイン スレッドに戻っていることを確認します。

しかし、なぜこれが必要なのか、本当にわかりません。

于 2013-04-17T06:49:10.977 に答える