AkiRoss AkiRoss - 2 months ago 25
C++ Question

Blocking signals on disabled widgets in Qt

I have a combo which is disabled, but adding an element to it will emit the

currentIndexChanged(int)
signal.

I expected signals to be naturally turned off when a widget is disabled, but it's not the case. I know there is
blockSignals(bool)
, but if there are many widgets whose signals must be "blocked when disabled",
blockSignals
would require a Boolean state for each widget.

How can I disable the signals sent by a widget when it is disabled (and not alter its
blockSignals
state)?

EDIT
To clarify: since this is a widget, user cannot interact with it when it's disabled, but some signals are emitted when altering the widget programmatically. In my case there are two interesting signals:
currentIndexChanged(int)
and
activated(int)


The problem in my code is that I sometimes alter the combo programmatically AND I wish it to emit a signal, and sometimes it's the user that alters the combo by interacting. That's why I am using
currentIndexChanged
and not
activated
.

In both cases, anyway, I don't want the signals to be emitted when widget is disabled.

Answer

The QComboBox signals are user interaction based from end user point of view if you only have a QComboBox and nothing else as your question seems to imply.

I simply cannot reproduce the issue. I have just made a short program where I cannot get any of the QComboBox signals emitted since I cannot simply interact with the widget.

Edit: It might be a good idea to upate your question with more context for the casual readers, but based on further clarification in comments, yes, programatically it might be the case, but then signals might be useful to process programmatically, too, with corresponding slots, so it is not a major improvement if Qt blocks them automatically.

Luckily, the feature you wish to have is already available:

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.

The return value is the previous value of signalsBlocked().

Note that the destroyed() signal will be emitted even if the signals for this object have been blocked.

If you want to do it for many widgets, create a simple function that you call instead of myWidget->setDisabled(true);:

inline bool disableAndBlockSignals(QWidget *widget)
{ 
    widget->setDisabled(true);
    return widget->blockSignals(true);
}

If you want to disable only some of them, say, currentIndexChanged, you can use disconnect manually then.

Comments