为什么信号/槽不能用于多线程?

发布于 2024-12-18 03:45:05 字数 1060 浏览 6 评论 0原文

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() 没有被调用?

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();
}

I'm trying to understand why b_slot() isn't getting called. Can anyone explain what's happening, and why b_slot() isn't getting called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

知你几分 2024-12-25 03:45:05

问题在于 A 类的 _timer 成员的所有权。

由于您没有显式初始化它,因此它是在没有父对象的情况下进行初始化的。因此,a.moveToThread(&aThread) 并未将计时器移至 aThread,之后事情就会变得混乱。

A 的构造函数更改为:

A() : _timer(this) {}

并且您的 b_slot() 将被调用。

The problem is the ownership of the _timer member of the A class.

Since you're not explicitly initializing it, it is initialized without a parent object. So the a.moveToThread(&aThread) isn't moving the timer to aThread, and things get confused after that.

Change A's constructor to:

A() : _timer(this) {}

and your b_slot() will get called.

柠檬 2024-12-25 03:45:05

问题是,当对象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;

The problem is that while object a is moved to aThread, _timer object still belongs to the original main thread. Try initializing _timer inside begin method like that:

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

private:

  QTimer *_timer;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文