Reputation: 3796
I want to set the currentIndex of a ComboBox dynamically without triggering my attached signal.
I am currently using a bool property to set a flag that gets cleared when my signal gets called.
Item {
property bool ignoreNextChanged: false
CustomCppItem {
id: customItem
onSomethingHappened: {
ignoreNextChanged = true
comboBox.currentIndex = 42
}
}
ComboBox {
id: comboBox
currentIndex: -1
onCurrentIndexChanged: {
if(ignoreNextChanged) {
ignoreNextChanged = false
return
}
// Removed code here
}
}
}
Coming from Qt/C++, I would like to use some sort of QSignalBlocker here instead of my own property.
Is there some equivalent in Qml/QtQuick2?
Upvotes: 1
Views: 851
Reputation: 7160
For this I would implement an attached type in c++ :
signalblockerattachedtype.h :
#ifndef SIGNALBLOCKERATTACHEDTYPE_H
#define SIGNALBLOCKERATTACHEDTYPE_H
#include <QObject>
#include <qqml.h>
class SignalBlockerAttachedType : public QObject
{
Q_OBJECT
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
public:
explicit SignalBlockerAttachedType(QObject *object = nullptr) : QObject(object), m_object(object)
{
}
~SignalBlockerAttachedType() {
if (m_object)
m_object->blockSignals(false);
}
bool enabled() const
{
return m_enabled;
}
void setEnabled(bool enabled)
{
if (m_enabled == enabled)
return;
if (m_object)
m_object->blockSignals(enabled);
m_enabled = enabled;
emit enabledChanged();
}
static SignalBlockerAttachedType *qmlAttachedProperties(QObject *object) {
return new SignalBlockerAttachedType(object);
}
signals:
void enabledChanged();
private:
bool m_enabled = false;
QObject *m_object;
};
QML_DECLARE_TYPEINFO(SignalBlockerAttachedType, QML_HAS_ATTACHED_PROPERTIES)
#endif // SIGNALBLOCKERATTACHEDTYPE_H
main.cpp :
#include "signalblockerattachedtype.h"
// ...
qmlRegisterUncreatableType<SignalBlockerAttachedType>("fr.grecko.SignalBlocker", 1, 0, "SignalBlocker", "SignalBlocker is only available as an attached type.");
// ...
engine.load(QUrl(QLatin1String("qrc:/usage.qml")));
usage.qml :
import fr.grecko.SignalBlocker 1.0
// ...
Item {
id: rootItem
property alias currentIndex: comboBox.currentIndex
onCurrentIndexChanged: {
// this won't get called from a change in onSomethingHappened
}
CustomCppItem {
id: customItem
onSomethingHappened: {
rootItem.SignalBlocker.enabled = true;
rootItem.currentIndex = 42
rootItem.SignalBlocker.enabled = false;
}
}
ComboBox {
id: comboBox
currentIndex: -1
}
}
Even though the SignalBlocker
works on the ComboBox
, you don't want to put it on the ComboBox
. Doing so will prevent it to update its display when the index changes.
In your situation, I don't think this solution is better than using a simple flag.
Upvotes: 2