現在、Qt のシグナルとスロットがスレッドでどのように動作するかを理解しようとしています。
次のコードで小さなテストを実行しようとしました。
class Worker : public QObject{
Q_OBJECT
public:
Worker(int _value){value = _value;}
~Worker(){};
int value;
public slots:
void changeValue(int newValue){value = newValue;}
void doWork(){
while(1){
_sleep(500);
std::cout << "Value is " << value << std::endl;
if(value == 0)break;
}
emit finished();
}
signals:
void finished();
};
class Manager : public QObject{
Q_OBJECT
public:
Manager(){}
~Manager(){};
signals:
void modifiedValue(int value);
public:
void changeTheValue(int value){emit modifiedValue(value);}
};
基本的に、ワーカーはvalue
メンバーを時々表示し、値を変更する機能を持つスロットを持っています。
manager は、 が呼び出されたときに新しい値を持つシグナルを発行する唯一の目的を持ちます。これは、メンバーchangeTheValue
を変更する Worker のスロットにマップされます。value
次にWorker
、次の方法でクラスをスレッドで機能させます。
QThread myThread;
Worker myWorker(10);
Manager manager;
myWorker.moveToThread(&myThread);
QObject::connect(&myThread, SIGNAL(started()), &myWorker,SLOT(doWork()));
QObject::connect(&myWorker, SIGNAL(finished()), &myThread, SLOT(quit()));
QObject::connect(&myWorker, SIGNAL(finished()), &myWorker, SLOT(deleteLater()));
QObject::connect(&myThread, SIGNAL(finished()), &myThread, SLOT(deleteLater()));
QObject::connect(&manager, SIGNAL(modifiedValue(int)),
&myWorker, SLOT(changeValue(int)));
myThread.start();
for(int i = 1; i < 10 ; i++){
_sleep(1000);
manager.changeTheValue(i);
}
manager.changeTheValue(0);
しかし、何も起こりません。値は変更されていないようです: 出力にはValue is 10
.
私が理解できないのは、シグナル/スロット マッピングがManager::modifiedValue
と でWorker::changeValue
機能していないように見えるのはなぜですか? doWork()
スレッドが現在ループを実行しているためだけですか? スロットへの呼び出しはどこで終了しますか (キューに入れられた、破棄された、その他) ?
シグナル/スロットメカニズムがスレッドでどのように機能するかについて、これ以上見つけることができませんでした(どのスレッドのコールスタックがスロットへの呼び出しを終了するかを説明するこのスレッドしか見つかりませんでしたが、回答で提供されたリンクは古くなっているようですQt 5 ホームにつながります)。
質問を要約するには:
- 値を変更するスロットへの呼び出しが何もしないのはなぜですか?
- これを機能させることは可能ですか (必要に応じてスレッドセーフを追加します)、どのように?