a concerned citizen
a concerned citizen

Reputation: 839

How to stop QComboBox/QSpinBox to emit signals when enabling/disabling them?

I have a small Qt plotting application and I am enabling/disabling widgets (combo/spin boxes) based on a "master" combo box. For example, say the master is combo1, which changes the entries in combo2, based on currentIndex(), enables/disables spin1, and sets a value for spin1 if a certain entry in combo1 is selected. There are more widgets than only these, though.

After the small discussion in the chat (and onwards), I used Qt::QueuedConnection with every connect(), but this didn't stop the re-enabled widgets to emit signals when re-enabled. This caused my many connect() to all be executed for all the re-enabled widgets, resulting in multiple plottings, which I want to avoid. As they are right now, (almost) all the widgets use plot() inside a connect(), so it's multiple signals to one slot.

My question: is there a way to prevent emitting the signals when the widgets are re-enabled? I could make plot() use some bool to check whether the plot has been executed and prevent further actions of the same type, but that would still cause the widgets to emit the signal and run plot(), even if the check will prevent the actual plotting, but that doesn't seem like the way to go. I would also prefer to avoid running installEventFilter(), or similar, as that would, most probably, slow down even more than the previous fix.

Upvotes: 1

Views: 2370

Answers (2)

cbuchart
cbuchart

Reputation: 11555

Another option, already mentioned in a comment, is to use QObject::blockSignals:

combo1->blockSignals(true);
// do what ever you need
combo1->blockSignals(false);

I find it easier to use and read. Also, there are many situations where you simply don't know / handle the connections.

Update

Since Qt 5.3 you also have QSignalBlocker, an exception-safe wrapper for blockSignals (internally it uses RAII to block signals in the constructor and restore them to their previous state on destruction):

{
  QSignalBlocker blocker{combo1}
  // do what ever you need
}

Upvotes: 8

znoopy2k
znoopy2k

Reputation: 58

Use disconnect before every connect to prevent multiple connections. Disconnecting a not connected slot is always allowed.

disconnect(spinbox1,...);
connect(spinbox1,...);

Blocking signals is also possible but I think you want the first solution.

From QtDocumentation:

bool QObject::blockSignals(bool block) If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it). If block is false, no such blocking will occur.

Upvotes: 3

Related Questions