为什么信号/槽不能与多线程一起工作


class A : public QObject{
  Q_OBJECT
signals:
  void a_sig();
public:
  A(){ }
public slots:
  void begin(){
    QObject::connect(&_timer, SIGNAL(timeout()), this, SIGNAL(a_sig()));
    _timer.start(1000); 
  }
private:
  QTimer _timer;
};

class B : public QObject{
  Q_OBJECT
public:
  B(){ value = 0; }
public slots:
  void b_slot(){
    ++value;
    QFile file("out.txt");
    file.open(QIODevice::WriteOnly);
    QTextStream out(&file);
    out << value << "n";
    file.close();
  }
private:
  int value;
};
int main(int argc, char **argv){
  QCoreApplication app(argc, argv);
  A a;
  B b;
  QThread aThread;
  QThread bThread;
  QObject::connect(&aThread, SIGNAL(started()), &a, SLOT(begin()));
  QObject::connect(&a, SIGNAL(a_sig()), &b, SLOT(b_slot()));
  a.moveToThread(&aThread);
  b.moveToThread(&bThread);
  aThread.start();
  bThread.start();
  return app.exec();
}

我想知道为什么b_slot()没有被调用。谁能解释一下发生了什么,为什么没有呼叫b_slot() ?

问题是A类中_timer成员的所有权。

由于没有显式初始化它,因此它在初始化时没有父对象。所以a.moveToThread(&aThread)没有将计时器移动到aThread,之后事情就变得混乱了。

修改A的构造函数为:

A() : _timer(this) {}

和你的b_slot()将被调用

问题是,虽然对象a被移动到aThread, _timer对象仍然属于原来的主线程。尝试在begin方法中初始化_timer,如下所示:

  void begin() {
    _timer = new QTimer;
    QObject::connect(_timer, SIGNAL(timeout()), this, SIGNAL(a_sig()));
    _timer->start(1000); 
  }
private:
  QTimer *_timer;

最新更新