为什么信号/槽在多线程中不起作用?

3
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()没有被调用吗?
2个回答

5
问题在于 A 类的 _timer 成员的所有权。
由于您没有明确初始化它,因此它是没有父对象初始化的。因此,a.moveToThread(&aThread) 没有将计时器移动到 aThread,之后的事情变得混乱不堪。
A 的构造函数更改为:
A() : _timer(this) {}

您的b_slot()将会被调用。


2
问题在于,虽然对象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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接