0

QThreadに関していくつかの問題と質問があります。1)QThread-> quit()を使用すると、finished()シグナルが出力されません。2)スレッドを構築して実行を終了する正しい方法はどのようになっていますか?

1)終了した信号コード-ヘッダーファイル。

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class MyThread: public QThread
{
     Q_OBJECT
public:
    explicit MyThread(QObject *parent = 0);

signals:

public slots:
    void finished();

protected:
    void run();

};

#endif // MYTHREAD_H

1)CPPファイル。

#include "MyThread.h"

MyThread::MyThread(QObject *parent) :
    QThread(parent)
{
}

void MyThread::finished()
{
    //never gets called...
    qDebug() << "Finished.";
}

void MyThread::run()
{
    connect(this, SIGNAL(finished()), this, SLOT(finished()), Qt::DirectConnection);
    this->exec();
}

私はこれでそれを構築しています:

MyThread *mThread = new MyThread(this); //What does parent do/mean ?
mThread->start();
Sleep(5000); //Windows.
mThread->quit(); //Finish thread.

Qt :: DirectConnectionが何をするのかさえ理解していません。すでにドキュメントを読んでいますが、Direct/Queued接続をいつどのように使用するかを実際には理解していません。

今頭に浮かんだもう一つの質問。

1)スレッドを自分で仕上げてクリーンアップするにはどうすればよいですか?(つまり、スレッドは自動的に終了してクリーンアップを実行する必要があります。)

2)新しいスレッドを作成/実行する理由とその理由を適切に説明するにはどうすればよいですか?

ありがとうございました。

4

1 に答える 1

2

サブクラス化しないでくださいQThread。代わりに、( を継承するQObject) ワーカー オブジェクトを作成し、 を作成してから、ワーカー オブジェクトでメソッドをQThread呼び出します。moveToThread()

class Worker : public QObject
{
  Q_OBJECT
public:
  Worker( QObject * parent = 0 )
    : QObject( parent )
  {
    connect( this, SIGNAL(done()), \
             this, SLOT(deleteLater())
            );
  }

public slots:
  void doWork() { // work, work }

signals:
  void done();  // emit this when you're finished with the work
};

// in your main function (or wherever)
QThread * thread = new QThread();
Worker * w = new Worker();
w->moveToThread( thread );
thread->start();
// clean up your thread
QObject::connect( w, SIGNAL(destroyed()), thread, SLOT(quit()) );
QObject::connect( thread, SIGNAL(finished()), thread(deleteLater()) );

// at some point, emit a signal connected to your workers 'doWork()' slot.
// when the work is finished, the worker and thread will both clean themselves up.

編集: Qt の古いバージョンを使用している場合はどうなりますか?

最近の Qt リリースでは、メソッドのデフォルトの実装は、スレッドのイベント ループを開始QThread::run()する callです。exec()古いバージョンの Qt をサポートしている場合は、上記のコードを機能させるために QThread をサブクラス化する必要があります。

class MyThread : public QThread
{
  void run() { exec(); }
};

次に、MyThread代わりに を使用するだけQThreadで、上記のすべてが引き続き適用されます。QThreadこの場合、特殊なスレッド クラス ( を呼び出したときに独自のイベント ループを実行するクラス) を作成しているため、サブクラス化することは完全に理にかなっていますstart()

スレッドのクリーンアップに関しては、上記が引き続き適用されます。

QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );

を呼び出すMyThread::quit()と、イベント ループが戻り、run()戻り、スレッド オブジェクトがfinished()シグナルを発します。MyThreadオブジェクトは実際にはメイン イベント ループ内に存在するため、スロットdeleteLater()呼び出しは引き続き配信されます。

于 2013-01-25T16:34:02.650 に答える