diff options
author | Michael Weghorn <[email protected]> | 2024-07-15 16:53:58 +0200 |
---|---|---|
committer | Michael Weghorn <[email protected]> | 2024-07-19 07:37:16 +0200 |
commit | b8b7c58402740204da72e1b1f4ea7321b7bfa540 (patch) | |
tree | 16abcedc50c2a89c790283f2eea5cd7cb1c3e247 | |
parent | 59133b16cd3adffc70833bb2b81332c9649fa51e (diff) |
a11y: Add property for QWidget's accessible ID
9ec1de2528b871099d416d15592fcc5ef9242a64 added
an Identifier role to QAccessible that can be
used to provide an identfier for reliable
identification by assistive technologies,
e.g. in automated tests.
As discussed in that commit's Gerrit change, add
a corresponding accessibleIdentifier property
to QWidget to allow easily setting a specific
identifier for widgets, in the same way that
an accessible name or description can be set.
This provides more flexibility than the default
logic that generates an identifier to be used
in platform bridges that is based on the object
or class names of the objects in the widget's
subtree.
(The only alternative so far to set a particular ID
not including the "object path" would have been to
provide a custom QAccessibleInterface
implementation with a corresponding
QAccessibleInterface::text implementation.)
Add an autotest testing both, the default platform
bridge logic and that the the newly added property
overrides that.
[ChangeLog][QtWidgets][QWidget] Add an accessibleId
property that allows to easily set a particular
accessible identifier for QWidgets that can be used
by assistive technologies to identify the widget.
Change-Id: If24e138c7d8fe4c78f25d3f0629a9520c352bacc
Reviewed-by: Volker Hilsheimer <[email protected]>
-rw-r--r-- | src/widgets/accessible/qaccessiblewidget.cpp | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 26 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.h | 3 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | tests/auto/other/qaccessibility/tst_qaccessibility.cpp | 29 |
5 files changed, 62 insertions, 0 deletions
diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index b0bb12ea86a..df1c8994567 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -383,6 +383,9 @@ QString QAccessibleWidget::text(QAccessible::Text t) const str = widget()->toolTip(); #endif break; + case QAccessible::Identifier: + str = widget()->accessibleIdentifier(); + break; case QAccessible::Help: #if QT_CONFIG(whatsthis) str = widget()->whatsThis(); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 514a2f21d5a..afa3438b682 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -11841,6 +11841,32 @@ QString QWidget::accessibleDescription() const Q_D(const QWidget); return d->accessibleDescription; } + +/*! + \property QWidget::accessibleIdentifier + + \brief the widget's identifier as seen by assistive technologies + + If set, the accessible identifier of a widget can be used by assistive + technologies in order to identify a specific widget, e.g. in automated + tests. + + \since 6.9 +*/ +void QWidget::setAccessibleIdentifier(const QString &identifier) +{ + Q_D(QWidget); + d->accessibleIdentifier = identifier; + QAccessibleEvent event(this, QAccessible::IdentifierChanged); + QAccessible::updateAccessibility(&event); +} + +QString QWidget::accessibleIdentifier() const +{ + Q_D(const QWidget); + return d->accessibleIdentifier; +} + #endif // QT_CONFIG(accessibility) #ifndef QT_NO_SHORTCUT diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index e5e83a43f2e..7ee4412d881 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -166,6 +166,7 @@ class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice #if QT_CONFIG(accessibility) Q_PROPERTY(QString accessibleName READ accessibleName WRITE setAccessibleName) Q_PROPERTY(QString accessibleDescription READ accessibleDescription WRITE setAccessibleDescription) + Q_PROPERTY(QString accessibleIdentifier READ accessibleIdentifier WRITE setAccessibleIdentifier) #endif Q_PROPERTY(Qt::LayoutDirection layoutDirection READ layoutDirection WRITE setLayoutDirection RESET unsetLayoutDirection) QDOC_PROPERTY(Qt::WindowFlags windowFlags READ windowFlags WRITE setWindowFlags) @@ -406,6 +407,8 @@ public: void setAccessibleName(const QString &name); QString accessibleDescription() const; void setAccessibleDescription(const QString &description); + QString accessibleIdentifier() const; + void setAccessibleIdentifier(const QString &identifier); #endif void setLayoutDirection(Qt::LayoutDirection direction); diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index b27ffdb1be6..f02aa3f9d2b 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -683,6 +683,7 @@ public: #if QT_CONFIG(accessibility) QString accessibleName; QString accessibleDescription; + QString accessibleIdentifier; #endif // Other variables. diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index e1452282042..5eb331b9300 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -20,6 +20,7 @@ #ifdef Q_OS_WIN #include <QtCore/private/qfunctions_win_p.h> #endif +#include <QtGui/private/qaccessiblebridgeutils_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qhighdpiscaling_p.h> @@ -221,6 +222,7 @@ private slots: void dockWidgetTest(); void comboBoxTest(); void accessibleName(); + void accessibleIdentifier(); #if QT_CONFIG(shortcut) void labelTest(); void relationTest(); @@ -644,6 +646,33 @@ void tst_QAccessibility::accessibleName() QTestAccessibility::clearEvents(); } +void tst_QAccessibility::accessibleIdentifier() +{ + const QString objectName("button_objectname"); + const QString id("mybutton"); + + QMainWindow mainWindow; + QPushButton button("a button", &mainWindow); + button.setObjectName(objectName); + mainWindow.show(); + + // verify that default implementation for platform bridges generates + // an accessible ID that's based on (i.e. somehow contains) the object name + QAccessibleInterface* accessible = QAccessible::queryAccessibleInterface(&button); + QVERIFY(QAccessibleBridgeUtils::accessibleId(accessible).contains(objectName)); + + // explicitly set an accessible ID, verify event and that the ID is set to + // that exact string (not only containing it) afterwards + QTestAccessibility::clearEvents(); + button.setAccessibleIdentifier(id); + QAccessibleEvent event(&button, QAccessible::IdentifierChanged); + QVERIFY(QTestAccessibility::containsEvent(&event)); + QCOMPARE(button.accessibleIdentifier(), id); + QCOMPARE(QAccessibleBridgeUtils::accessibleId(accessible), id); + + QTestAccessibility::clearEvents(); +} + // note: color should probably always be part of the attributes void tst_QAccessibility::textAttributes_data() { |