scmg
scmg

Reputation: 1894

Qt - invoke slot only when both signals are emitted

I have 3 processes: A, B and Final. Final depends on both A and B and can/must only be updated when both A and B are updated. There is a signal dataChanged that updates both A and B (and so Final as well). Slots update_A and update_B are also invoked by other signals.

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

Is there anyway to combine the signals with the AND operator to get rid off using pA and pB? Or did I use signals and slots in a wrong way?

EDIT: Sorry that I forgot to mention: update_A and update_B are also invoked by other signals, so I have to keep them as separated slots. And I updated the question and code above.

Upvotes: 2

Views: 380

Answers (1)

Toby Speight
Toby Speight

Reputation: 30831

No, there's no supplied signal combination operators in Qt. You'll need to implement your own, as you have done, or like:

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

If you use this pattern frequently, it may be worthwhile to define an object class with the sole responsibility of logical operations on signal sequences. To be complete, you would want 'A before B' and 'A after B' operators too.

Upvotes: 1

Related Questions