QAction: add exclusionPolicy property
When set to ExclusiveOptional, the new exclusionPolicy property let the user uncheck the active checkable action in an exclusive group. [ChangeLog][QtWidgets][QActionGroup] Added new exclusionPolicy property. Set it to ExclusiveOptional to allow unchecking the active checkable action in an exclusive group. Change-Id: I61a9885cfd076d631cddf8c08313e4b488e5dc38 Fixes: QTBUG-71160 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
b17e05729e
commit
c826e67765
@ -1153,8 +1153,9 @@ void QAction::activate(ActionEvent event)
|
||||
if(event == Trigger) {
|
||||
QPointer<QObject> guard = this;
|
||||
if(d->checkable) {
|
||||
// the checked action of an exclusive group cannot be unchecked
|
||||
if (d->checked && (d->group && d->group->isExclusive()
|
||||
// the checked action of an exclusive group may not be unchecked
|
||||
if (d->checked && (d->group
|
||||
&& d->group->exclusionPolicy() == QActionGroup::ExclusionPolicy::Exclusive
|
||||
&& d->group->checkedAction() == this)) {
|
||||
if (!guard.isNull())
|
||||
emit triggered(true);
|
||||
|
@ -52,12 +52,16 @@ class QActionGroupPrivate : public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QActionGroup)
|
||||
public:
|
||||
QActionGroupPrivate() : exclusive(1), enabled(1), visible(1) { }
|
||||
QActionGroupPrivate() : enabled(1),
|
||||
visible(1),
|
||||
exclusionPolicy(QActionGroup::ExclusionPolicy::Exclusive)
|
||||
{
|
||||
}
|
||||
QList<QAction *> actions;
|
||||
QPointer<QAction> current;
|
||||
uint exclusive : 1;
|
||||
uint enabled : 1;
|
||||
uint visible : 1;
|
||||
QActionGroup::ExclusionPolicy exclusionPolicy;
|
||||
|
||||
private:
|
||||
void _q_actionTriggered(); //private slot
|
||||
@ -70,7 +74,7 @@ void QActionGroupPrivate::_q_actionChanged()
|
||||
Q_Q(QActionGroup);
|
||||
QAction *action = qobject_cast<QAction*>(q->sender());
|
||||
Q_ASSERT_X(action != 0, "QWidgetGroup::_q_actionChanged", "internal error");
|
||||
if(exclusive) {
|
||||
if (exclusionPolicy != QActionGroup::ExclusionPolicy::None) {
|
||||
if (action->isChecked()) {
|
||||
if (action != current) {
|
||||
if(current)
|
||||
@ -127,12 +131,17 @@ void QActionGroupPrivate::_q_actionHovered()
|
||||
actions is chosen. Each action in an action group emits its
|
||||
triggered() signal as usual.
|
||||
|
||||
As stated above, an action group is \l exclusive by default; it
|
||||
ensures that only one checkable action is active at any one time.
|
||||
As stated above, an action group is exclusive by default; it
|
||||
ensures that at most only one checkable action is active at any one time.
|
||||
If you want to group checkable actions without making them
|
||||
exclusive, you can turn of exclusiveness by calling
|
||||
exclusive, you can turn off exclusiveness by calling
|
||||
setExclusive(false).
|
||||
|
||||
By default the active action of an exclusive group cannot be unchecked.
|
||||
In some cases it may be useful to allow unchecking all the actions,
|
||||
you can allow this by calling
|
||||
setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional).
|
||||
|
||||
Actions can be added to an action group using addAction(), but it
|
||||
is usually more convenient to specify a group when creating
|
||||
actions; this ensures that actions are automatically created with
|
||||
@ -145,11 +154,34 @@ void QActionGroupPrivate::_q_actionHovered()
|
||||
\sa QAction
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QActionGroup::ExclusionPolicy
|
||||
|
||||
This enum specifies the different policies that can be used to
|
||||
control how the group performs exclusive checking on checkable actions.
|
||||
|
||||
\value None
|
||||
The actions in the group can be checked independently of each other.
|
||||
|
||||
\value Exclusive
|
||||
Exactly one action can be checked at any one time.
|
||||
This is the default policy.
|
||||
|
||||
\value ExclusiveOptional
|
||||
At most one action can be checked at any one time. The actions
|
||||
can also be all unchecked.
|
||||
|
||||
\sa exclusionPolicy
|
||||
\since 5.14
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an action group for the \a parent object.
|
||||
|
||||
The action group is exclusive by default. Call setExclusive(false)
|
||||
to make the action group non-exclusive.
|
||||
to make the action group non-exclusive. To make the group exclusive
|
||||
but allow unchecking the active action call instead
|
||||
setExclusionPolicy(QActionGroup::ExclusionPolicy::ExclusiveOptional)
|
||||
*/
|
||||
QActionGroup::QActionGroup(QObject* parent) : QObject(*new QActionGroupPrivate, parent)
|
||||
{
|
||||
@ -258,26 +290,56 @@ QList<QAction*> QActionGroup::actions() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QActionGroup::exclusive
|
||||
\brief whether the action group does exclusive checking
|
||||
\brief Enable or disable the group exclusion checking
|
||||
|
||||
If exclusive is true, only one checkable action in the action group
|
||||
can ever be active at any time. If the user chooses another
|
||||
checkable action in the group, the one they chose becomes active and
|
||||
the one that was active becomes inactive.
|
||||
This is a convenience method that calls
|
||||
setExclusionPolicy(ExclusionPolicy::Exclusive).
|
||||
|
||||
\sa QAction::checkable
|
||||
\sa QActionGroup::exclusionPolicy
|
||||
*/
|
||||
void QActionGroup::setExclusive(bool b)
|
||||
{
|
||||
Q_D(QActionGroup);
|
||||
d->exclusive = b;
|
||||
setExclusionPolicy(b ? QActionGroup::ExclusionPolicy::Exclusive
|
||||
: QActionGroup::ExclusionPolicy::None);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returs true if the group is exclusive
|
||||
|
||||
The group is exclusive if the ExclusionPolicy is either Exclusive
|
||||
or ExclusionOptional.
|
||||
|
||||
*/
|
||||
bool QActionGroup::isExclusive() const
|
||||
{
|
||||
return exclusionPolicy() != QActionGroup::ExclusionPolicy::None;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QActionGroup::exclusionPolicy
|
||||
\brief This property holds the group exclusive checking policy
|
||||
|
||||
If exclusionPolicy is set to Exclusive, only one checkable
|
||||
action in the action group can ever be active at any time. If the user
|
||||
chooses another checkable action in the group, the one they chose becomes
|
||||
active and the one that was active becomes inactive. If exclusionPolicy is
|
||||
set to ExclusionOptional the group is exclusive but the active checkable
|
||||
action in the group can be unchecked leaving the group with no actions
|
||||
checked.
|
||||
|
||||
\sa QAction::checkable
|
||||
\since 5.14
|
||||
*/
|
||||
void QActionGroup::setExclusionPolicy(QActionGroup::ExclusionPolicy policy)
|
||||
{
|
||||
Q_D(QActionGroup);
|
||||
d->exclusionPolicy = policy;
|
||||
}
|
||||
|
||||
QActionGroup::ExclusionPolicy QActionGroup::exclusionPolicy() const
|
||||
{
|
||||
Q_D(const QActionGroup);
|
||||
return d->exclusive;
|
||||
return d->exclusionPolicy;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -55,11 +55,18 @@ class Q_WIDGETS_EXPORT QActionGroup : public QObject
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QActionGroup)
|
||||
|
||||
Q_PROPERTY(bool exclusive READ isExclusive WRITE setExclusive)
|
||||
Q_PROPERTY(QActionGroup::ExclusionPolicy exclusionPolicy READ exclusionPolicy WRITE setExclusionPolicy)
|
||||
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
|
||||
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
|
||||
|
||||
public:
|
||||
enum class ExclusionPolicy {
|
||||
None,
|
||||
Exclusive,
|
||||
ExclusiveOptional
|
||||
};
|
||||
Q_ENUM(ExclusionPolicy)
|
||||
|
||||
explicit QActionGroup(QObject* parent);
|
||||
~QActionGroup();
|
||||
|
||||
@ -73,6 +80,7 @@ public:
|
||||
bool isExclusive() const;
|
||||
bool isEnabled() const;
|
||||
bool isVisible() const;
|
||||
ExclusionPolicy exclusionPolicy() const;
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
@ -80,6 +88,7 @@ public Q_SLOTS:
|
||||
inline void setDisabled(bool b) { setEnabled(!b); }
|
||||
void setVisible(bool);
|
||||
void setExclusive(bool);
|
||||
void setExclusionPolicy(ExclusionPolicy policy);
|
||||
|
||||
Q_SIGNALS:
|
||||
void triggered(QAction *);
|
||||
|
@ -41,6 +41,7 @@ private slots:
|
||||
void enabledPropagation();
|
||||
void visiblePropagation();
|
||||
void exclusive();
|
||||
void exclusiveOptional();
|
||||
void separators();
|
||||
void testActionInTwoQActionGroup();
|
||||
void unCheckCurrentAction();
|
||||
@ -151,6 +152,52 @@ void tst_QActionGroup::exclusive()
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
}
|
||||
|
||||
void tst_QActionGroup::exclusiveOptional()
|
||||
{
|
||||
QActionGroup group(0);
|
||||
group.setExclusive(true);
|
||||
QVERIFY( group.isExclusive() );
|
||||
|
||||
QAction* actOne = new QAction( &group );
|
||||
actOne->setCheckable( true );
|
||||
QAction* actTwo = new QAction( &group );
|
||||
actTwo->setCheckable( true );
|
||||
QAction* actThree = new QAction( &group );
|
||||
actThree->setCheckable( true );
|
||||
|
||||
QVERIFY( !actOne->isChecked() );
|
||||
QVERIFY( !actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
|
||||
actOne->trigger();
|
||||
QVERIFY( actOne->isChecked() );
|
||||
QVERIFY( !actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
|
||||
actOne->trigger();
|
||||
QVERIFY( actOne->isChecked() );
|
||||
QVERIFY( !actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
|
||||
group.setExclusionPolicy( QActionGroup::ExclusionPolicy::ExclusiveOptional );
|
||||
QVERIFY( group.isExclusive() );
|
||||
|
||||
actOne->trigger();
|
||||
QVERIFY( !actOne->isChecked() );
|
||||
QVERIFY( !actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
|
||||
actTwo->trigger();
|
||||
QVERIFY( !actOne->isChecked() );
|
||||
QVERIFY( actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
|
||||
actTwo->trigger();
|
||||
QVERIFY( !actOne->isChecked() );
|
||||
QVERIFY( !actTwo->isChecked() );
|
||||
QVERIFY( !actThree->isChecked() );
|
||||
}
|
||||
|
||||
void tst_QActionGroup::separators()
|
||||
{
|
||||
QMainWindow mw;
|
||||
|
Loading…
x
Reference in New Issue
Block a user