Qt - 仅在发出两个信号时才调用插槽

Posted

技术标签:

【中文标题】Qt - 仅在发出两个信号时才调用插槽【英文标题】:Qt - invoke slot only when both signals are emitted 【发布时间】:2016-07-04 15:30:41 【问题描述】:

我有 3 个进程:ABFinalFinal 取决于 AB 并且只能/必须在 AB 都更新时更新。有一个信号dataChanged 会同时更新AB(以及Final)。插槽update_Aupdate_B 也被其他信号调用。

MainWindow::MainWindow(QWidget* parent)
  : QMainWindow(parent),
    pA(false),
    pB(false)

...
connect(this, &MainWindow::xChanged, this, &MainWindow::update_A);
connect(this, &MainWindow::yChanged, this, &MainWindow::update_B);
connect(myObj, &MyClass::dataChanged, this, &MainWindow::update_A);
connect(myObj, &MyClass::dataChanged, this, &MainWindow::update_B);
connect(this, &MainWindow::a_Updated, this, &MainWindow::update_final);
connect(this, &MainWindow::b_Updated, this, &MainWindow::update_final);
...


void MainWindow::update_A() 
  if (!this.pA) 
    // do something 
  
  this.pA = true;
  emit a_Updated;


void MainWindow::update_B() 
  if (!this.pB) 
    // do something 
  
  this.pB = true;
  emit b_Updated;


void MainWindow::update_final() 
  if (this.pA && this.pB) 
    // do something
    this.pA = false;
    this.pB = false;
  

是否可以将信号与 AND 运算符结合起来使用 pApB?还是我用错了信号和槽?

编辑:对不起,我忘了提:update_Aupdate_B 也被其他信号调用,所以我必须将它们保持为单独的插槽。我更新了上面的问题和代码。

【问题讨论】:

update_A 和 update_B 是否阻塞?所有对象都在一个线程中吗?因为插槽是按照它们连接的顺序调用的,所以一旦 update_A 完成,总是会调用 update_B。如果在其他 2 个连接后将最后一个插槽连接到 dataChanged,则一旦 update_B 完成,将调用该插槽 为什么不使用单个槽来调用这些函数(反过来又可以返回bool 来检查状态)并且只有在所有函数都成功时才调用Finish 由于插槽也连接到其他信号,我无法将它们组合起来。 dataChanged 只是一个调用两者的信号。有些信号只调用其中一个槽,但一旦调用了两个槽,update_final 也必须被调用。 【参考方案1】:

不,Qt 中没有提供信号组合运算符。您需要实现自己的,就像您已经完成的那样,或者像这样:

void MainWindow::update_A() 
  if (!pA) 
    // do something 
  
  pA = true;
  if (pA && pB)
      emit ab_Updated();

如果您经常使用此模式,则可能值得定义一个对象类来单独负责信号序列的逻辑操作。为了完整起见,您还需要 'A before B' 和 'A after B' 运算符。

【讨论】:

你能给我一个这样的例子吗? 不,我不会举个例子——你有逻辑,只是将相关代码分离到自己的类中。除非您的整个应用程序是通过将信号处理程序组合在一起来构建的(在这种情况下,您应该阅读 Qt 的状态机框架,我认为),否则这甚至都不值得付出努力。

以上是关于Qt - 仅在发出两个信号时才调用插槽的主要内容,如果未能解决你的问题,请参考以下文章

Qt 插槽同时断开连接并从不同线程调用

跟随发出的信号到其连接的插槽?

打印信号/插槽的跟踪称为

QtConcurrent::run 发出信号

在 moveToThread() 之后未调用 Qt 4.8 信号/插槽

在 QThread::run 中间调用了一个插槽