aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp1
-rw-r--r--src/imports/templates/qtquicktemplates2plugin.cpp1
-rw-r--r--src/quicktemplates2/qquickbuttongroup.cpp50
-rw-r--r--src/quicktemplates2/qquickbuttongroup_p.h5
-rw-r--r--tests/auto/controls/data/tst_buttongroup.qml62
5 files changed, 112 insertions, 7 deletions
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index aa4eb295..48d027dd 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -158,6 +158,7 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
// QtQuick.Controls 2.3 (new types in Qt 5.10)
qmlRegisterType<QQuickAction>(uri, 2, 3, "Action");
qmlRegisterType<QQuickActionGroup>(uri, 2, 3, "ActionGroup");
+ qmlRegisterType<QQuickButtonGroup, 3>(uri, 2, 3, "ButtonGroup");
qmlRegisterType<QQuickIcon>();
}
diff --git a/src/imports/templates/qtquicktemplates2plugin.cpp b/src/imports/templates/qtquicktemplates2plugin.cpp
index e16a0e45..32779b4a 100644
--- a/src/imports/templates/qtquicktemplates2plugin.cpp
+++ b/src/imports/templates/qtquicktemplates2plugin.cpp
@@ -260,6 +260,7 @@ void QtQuickTemplates2Plugin::registerTypes(const char *uri)
qmlRegisterType<QQuickAbstractButton, 3>(uri, 2, 3, "AbstractButton");
qmlRegisterType<QQuickAction>(uri, 2, 3, "Action");
qmlRegisterType<QQuickActionGroup>(uri, 2, 3, "ActionGroup");
+ qmlRegisterType<QQuickButtonGroup, 3>(uri, 2, 3, "ButtonGroup");
qmlRegisterType<QQuickIcon>();
qmlRegisterType<QQuickRangeSlider, 3>(uri, 2, 3, "RangeSlider");
qmlRegisterType<QQuickScrollBar, 3>(uri, 2, 3, "ScrollBar");
diff --git a/src/quicktemplates2/qquickbuttongroup.cpp b/src/quicktemplates2/qquickbuttongroup.cpp
index a9c0d435..705224d6 100644
--- a/src/quicktemplates2/qquickbuttongroup.cpp
+++ b/src/quicktemplates2/qquickbuttongroup.cpp
@@ -154,7 +154,11 @@ class QQuickButtonGroupPrivate : public QObjectPrivate
Q_DECLARE_PUBLIC(QQuickButtonGroup)
public:
- QQuickButtonGroupPrivate() : checkedButton(nullptr) { }
+ QQuickButtonGroupPrivate()
+ : exclusive(true),
+ checkedButton(nullptr)
+ {
+ }
void clear();
void buttonClicked();
@@ -165,6 +169,7 @@ public:
static QQuickAbstractButton *buttons_at(QQmlListProperty<QQuickAbstractButton> *prop, int index);
static void buttons_clear(QQmlListProperty<QQuickAbstractButton> *prop);
+ bool exclusive;
QQuickAbstractButton *checkedButton;
QVector<QQuickAbstractButton*> buttons;
};
@@ -190,6 +195,8 @@ void QQuickButtonGroupPrivate::buttonClicked()
void QQuickButtonGroupPrivate::_q_updateCurrent()
{
Q_Q(QQuickButtonGroup);
+ if (!exclusive)
+ return;
QQuickAbstractButton *button = qobject_cast<QQuickAbstractButton*>(q->sender());
if (button && button->isChecked())
q->setCheckedButton(button);
@@ -246,9 +253,12 @@ QQuickButtonGroupAttached *QQuickButtonGroup::qmlAttachedProperties(QObject *obj
/*!
\qmlproperty AbstractButton QtQuick.Controls::ButtonGroup::checkedButton
- This property holds the currently selected button, or \c null if there is none.
+ This property holds the currently selected button in an exclusive group,
+ or \c null if there is none or the group is non-exclusive.
+
+ By default, it is the first checked button added to an exclusive button group.
- By default, it is the first checked button added to the button group.
+ \sa exclusive
*/
QQuickAbstractButton *QQuickButtonGroup::checkedButton() const
{
@@ -308,6 +318,38 @@ QQmlListProperty<QQuickAbstractButton> QQuickButtonGroup::buttons()
}
/*!
+ \since QtQuick.Controls 2.3
+ \qmlproperty bool QtQuick.Controls::ButtonGroup::exclusive
+
+ This property holds whether the button group is exclusive. The default value is \c true.
+
+ If this property is \c true, then only one button in the group can be checked at any given time.
+ The user can click on any button to check it, and that button will replace the existing one as
+ the checked button in the group.
+
+ In an exclusive group, the user cannot uncheck the currently checked button by clicking on it;
+ instead, another button in the group must be clicked to set the new checked button for that group.
+
+ In a non-exclusive group, checking and unchecking buttons does not affect the other buttons in
+ the group. Furthermore, the value of the \l checkedButton property is \c null.
+*/
+bool QQuickButtonGroup::isExclusive() const
+{
+ Q_D(const QQuickButtonGroup);
+ return d->exclusive;
+}
+
+void QQuickButtonGroup::setExclusive(bool exclusive)
+{
+ Q_D(QQuickButtonGroup);
+ if (d->exclusive == exclusive)
+ return;
+
+ d->exclusive = exclusive;
+ emit exclusiveChanged();
+}
+
+/*!
\qmlmethod void QtQuick.Controls::ButtonGroup::addButton(AbstractButton button)
Adds a \a button to the button group.
@@ -328,7 +370,7 @@ void QQuickButtonGroup::addButton(QQuickAbstractButton *button)
QObjectPrivate::connect(button, &QQuickAbstractButton::clicked, d, &QQuickButtonGroupPrivate::buttonClicked);
QObjectPrivate::connect(button, &QQuickAbstractButton::checkedChanged, d, &QQuickButtonGroupPrivate::_q_updateCurrent);
- if (button->isChecked())
+ if (d->exclusive && button->isChecked())
setCheckedButton(button);
d->buttons.append(button);
diff --git a/src/quicktemplates2/qquickbuttongroup_p.h b/src/quicktemplates2/qquickbuttongroup_p.h
index 21deb035..5fe1858d 100644
--- a/src/quicktemplates2/qquickbuttongroup_p.h
+++ b/src/quicktemplates2/qquickbuttongroup_p.h
@@ -64,6 +64,7 @@ class Q_QUICKTEMPLATES2_PRIVATE_EXPORT QQuickButtonGroup : public QObject
Q_OBJECT
Q_PROPERTY(QQuickAbstractButton *checkedButton READ checkedButton WRITE setCheckedButton NOTIFY checkedButtonChanged)
Q_PROPERTY(QQmlListProperty<QQuickAbstractButton> buttons READ buttons NOTIFY buttonsChanged FINAL)
+ Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive NOTIFY exclusiveChanged FINAL REVISION 3)
public:
explicit QQuickButtonGroup(QObject *parent = nullptr);
@@ -76,6 +77,9 @@ public:
QQmlListProperty<QQuickAbstractButton> buttons();
+ bool isExclusive() const;
+ void setExclusive(bool exclusive);
+
public Q_SLOTS:
void addButton(QQuickAbstractButton *button);
void removeButton(QQuickAbstractButton *button);
@@ -83,6 +87,7 @@ public Q_SLOTS:
Q_SIGNALS:
void checkedButtonChanged();
void buttonsChanged();
+ Q_REVISION(3) void exclusiveChanged();
Q_REVISION(1) void clicked(QQuickAbstractButton *button);
private:
diff --git a/tests/auto/controls/data/tst_buttongroup.qml b/tests/auto/controls/data/tst_buttongroup.qml
index bde655da..cbbaec5a 100644
--- a/tests/auto/controls/data/tst_buttongroup.qml
+++ b/tests/auto/controls/data/tst_buttongroup.qml
@@ -50,7 +50,7 @@
import QtQuick 2.2
import QtTest 1.0
-import QtQuick.Controls 2.2
+import QtQuick.Controls 2.3
TestCase {
id: testCase
@@ -66,6 +66,11 @@ TestCase {
}
Component {
+ id: nonExclusiveGroup
+ ButtonGroup { exclusive: false }
+ }
+
+ Component {
id: signalSpy
SignalSpy { }
}
@@ -88,6 +93,14 @@ TestCase {
QtObject { }
}
+ function test_defaults() {
+ var group = createTemporaryObject(buttonGroup, testCase)
+ verify(group)
+ compare(group.buttons.length, 0)
+ compare(group.checkedButton, null)
+ compare(group.exclusive, true)
+ }
+
function test_current() {
var group = createTemporaryObject(buttonGroup, testCase)
verify(group)
@@ -200,8 +213,15 @@ TestCase {
compare(buttonsSpy.count, 5)
}
- function test_clicked() {
- var group = createTemporaryObject(buttonGroup, testCase)
+ function test_clicked_data() {
+ return [
+ {tag: "exclusive", exclusive: true},
+ {tag: "non-exclusive", exclusive: false}
+ ]
+ }
+
+ function test_clicked(data) {
+ var group = createTemporaryObject(buttonGroup, testCase, {exclusive: data.exclusive})
verify(group)
var clickedSpy = createTemporaryObject(signalSpy, testCase, {target: group, signalName: "clicked"})
@@ -346,4 +366,40 @@ TestCase {
verify(container.group.checkedButton)
compare(container.group.checkedButton.objectName, "0")
}
+
+ function test_nonExclusive() {
+ var group = createTemporaryObject(nonExclusiveGroup, testCase)
+ verify(group)
+
+ var button1 = createTemporaryObject(button, testCase, {checked: true})
+ group.addButton(button1)
+ compare(button1.checked, true)
+ compare(group.checkedButton, null)
+
+ var button2 = createTemporaryObject(button, testCase, {checked: true})
+ group.addButton(button2)
+ compare(button1.checked, true)
+ compare(button2.checked, true)
+ compare(group.checkedButton, null)
+
+ button1.checked = false
+ compare(button1.checked, false)
+ compare(button2.checked, true)
+ compare(group.checkedButton, null)
+
+ button2.checked = false
+ compare(button1.checked, false)
+ compare(button2.checked, false)
+ compare(group.checkedButton, null)
+
+ button1.checked = true
+ compare(button1.checked, true)
+ compare(button2.checked, false)
+ compare(group.checkedButton, null)
+
+ button2.checked = true
+ compare(button1.checked, true)
+ compare(button2.checked, true)
+ compare(group.checkedButton, null)
+ }
}