| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the documentation of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:FDL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Free Documentation License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Free |
| ** Documentation License version 1.3 as published by the Free Software |
| ** Foundation and appearing in the file included in the packaging of |
| ** this file. Please review the following information to ensure |
| ** the GNU Free Documentation License version 1.3 requirements |
| ** will be met: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \group accessibility |
| \brief Functions ensuring communication between accessible applications and accessibility tools. |
| \title Accessibility Classes |
| */ |
| |
| /*! |
| \page accessible.html |
| \title Accessibility |
| \brief How to make your applications accessible to those with disabilities. |
| |
| \nextpage Accessibility for QWidget Applications |
| |
| \ingroup best-practices |
| |
| \tableofcontents |
| |
| |
| \section1 Introduction |
| |
| Accessibility in computer software is making applications usable |
| for people with different abilities. |
| It is important to take different people's needs into account, for example, |
| in case of low vision, hearing, dexterity, or cognitive problems. |
| Some examples of accessibility measures are |
| keyboard shortcuts, a high-contrast user interface that uses |
| specially selected colors and fonts, or support for assistive tools |
| such as screen readers and braille displays. |
| |
| A basic checklist that any application should aim for: |
| \list |
| \li \b {Usability} - Usability and user centric design generally lead to |
| more usable applications, including improvements for people with various abilities. |
| \li \b {Fonts} - Font settings should follow the system/platform. This allows users to select |
| fonts for readability and increasing the font size. |
| \li \b {Colors} - Provide enough contrast and consider the most common cases of low |
| vision and color blindness. Make sure that the application is usable, for example, |
| for people with red/green blindness, and don't depend on colors only. |
| \li \b {Scalable UI} - A user interface that works in various sizes and properly supports |
| different fonts and accommodates size changes. |
| \li \b {Sounds} - Do not exclusively rely on sound notifications, provide a visual alternative |
| when a sound signal is imperative to using the application. |
| \li \b {Spelling} - Offer spell checking wherever it makes sense, even when only a single word is expected. |
| \li \b {Assistive Technology} - Support the use of assistive tools (AT). Either use standard widgets/controls |
| which support ATs out of the box, or make sure that your custom widgets and controls support |
| accessibility properly. In order to learn more about this read on below. |
| \endlist |
| |
| This part of the documentation assumes that the basics for accessibility, |
| which go hand in hand with usability, are already in good shape. |
| The rest of this document focuses more specifically on supporting assistive technology. |
| |
| Assistive Tools (or ATs) come in great variety and help users with different tasks. |
| For this reason what individual applications offer (with the help of Qt) is a generic |
| API that allows to inspect what is on screen in a semantic way and offers the typical |
| interactions with the UI elements. |
| |
| Applications do not usually communicate directly with the |
| assistive tools, but through a platform specific API. |
| Generally the communication with the ATs works though an IPC mechanism. |
| Semantic information about user interface elements, such as |
| buttons and scroll bars, is exposed to the assistive technologies. |
| Qt supports UI Automation on Windows, |
| \macos Accessibility on \macos, and AT-SPI via DBus on Unix/X11. |
| The platform specific technologies are abstracted by Qt, |
| so that applications do not need any platform specific changes to work with the different |
| native APIs. Qt tries to make adding accessibility support to your application as easy |
| as possible, only a few changes from your side may be required to allow even more users to enjoy it. |
| |
| The main reason to consult this documentation is to learn how to make custom \l QWidget subclasses |
| and \l {QQuickItem}s accessible. |
| |
| In this overview document, we will examine the overall Qt |
| accessibility architecture, and how to implement accessibility for |
| custom widgets and elements. |
| |
| \section1 Making Applications Accessible |
| |
| These two pages focus on giving an overview of how to achieve |
| good accessibility: |
| |
| \l{Accessibility for QWidget Applications} |
| |
| \l{Accessibility for Qt Quick Applications} |
| |
| These classes provide support for accessible applications: |
| \annotatedlist accessibility |
| */ |
| |
| |
| /*! |
| \page accessible-qwidget.html |
| \title Accessibility for QWidget Applications |
| \brief How to make your applications accessible to those with disabilities. |
| \previouspage Accessibility |
| \nextpage Accessibility for Qt Quick Applications |
| |
| \tableofcontents |
| |
| \section1 Introduction |
| |
| We will focus on the Qt accessibility interface \l {QAccessibleInterface} |
| and how to make applications accessible. |
| |
| \section2 Accessibility in QWidget based applications |
| |
| When we communicate with the assistive technologies, we need to |
| describe Qt's user interface in a way that they can understand. Qt |
| applications use QAccessibleInterface to expose information about the |
| individual UI elements. Currently, Qt provides support for its widgets |
| and widget parts, e.g., slider handles, but the interface could |
| also be implemented for any QObject if necessary. QAccessible |
| contains enums that describe the UI. We will examine the enums |
| in the course of this document. |
| |
| The structure of the UI is represented as a tree of |
| QAccessibleInterface subclasses. This is often a mirror of the |
| hierarchy of QWidgets that make up the UI of the application. |
| |
| Servers notify clients through \l{QAccessible::}{updateAccessibility()} |
| about changes in objects by sending events, and the clients |
| register to receive the events. The available events are defined |
| by the QAccessible::Event enum. The clients may then query for |
| the object that generated the event through |
| \l QAccessible::queryAccessibleInterface(). |
| |
| The members and enums in QAccessible are used to describe |
| accessible objects: |
| |
| \list |
| \li \l{QAccessible::}{Role}: Describes the role the object |
| fills in the user interface, e.g., if it is a |
| window, a text edit, or a cell in a table. |
| \li \l{QAccessible::}{Relation}: Describes the relationship |
| between objects in the object hierarchy. |
| \li \l{QAccessible::}{State}: The objects can be in a number |
| of different states. Examples of states are whether |
| the object is disabled, if it has focus, |
| or if it provides a pop-up menu. |
| \endlist |
| |
| The clients also have some possibilities to get the content of |
| objects, e.g., a button's text; the object provides strings |
| defined by the QAccessible::Text enum, that give information |
| about content. |
| |
| |
| \section2 The Accessible Object Tree |
| |
| As mentioned, a tree structure is built from the accessible |
| objects of an application. By navigating through the tree, the |
| clients can access all elements in the UI. Object relations give |
| clients information about the UI. For instance, a slider handle is |
| a child of the slider to which it belongs. QAccessible::Relation |
| describes the various relationships the clients can ask objects |
| for. |
| |
| Note that there are no direct mapping between the Qt QObject tree |
| and the accessible object tree. For instance, scroll bar handles |
| are accessible objects but are not widgets or objects in Qt. |
| |
| AT-Clients have access to the accessibility object tree through |
| the root object in the tree, which is the QApplication. They can |
| navigate the tree with the QAccessibleInterface::parent(), QAccessibleInterface::childCount() |
| and QAccessibleInterface::child() functions. |
| |
| Qt provides accessible interfaces for its widgets and for Qt Quick Controls. |
| Interfaces for any QObject subclass can be requested through |
| QAccessible::queryInterface(). A default implementation is |
| provided if a more specialized interface is not defined. An |
| AT-Client cannot acquire an interface for accessible objects that |
| do not have an equivalent QObject, e.g., scroll bar handles, but |
| they appear as normal objects through interfaces of parent |
| accessible objects, e.g., you can query their relationships with |
| QAccessibleInterface::relations(). |
| |
| To illustrate, we present an image of an accessible object tree. |
| Beneath the tree is a table with examples of object relationships. |
| |
| \image accessibleobjecttree.png |
| |
| The labels in top-down order are: the QAccessibleInterface class |
| name, the widget for which an interface is provided, and the |
| \l{QAccessible::}{Role} of the object. The Position, PageLeft and |
| PageRight correspond to the slider handle, the slider groove left |
| and the slider groove right, respectively. These accessible objects |
| do not have an equivalent QObject. |
| |
| \table 40% |
| \header |
| \li Source Object |
| \li Target Object |
| \li Relation |
| \row |
| \li Slider |
| \li Indicator |
| \li Controller |
| \row |
| \li Indicator |
| \li Slider |
| \li Controlled |
| \row |
| \li Slider |
| \li Application |
| \li Ancestor |
| \row |
| \li Application |
| \li Slider |
| \li Child |
| \row |
| \li PushButton |
| \li Indicator |
| \li Sibling |
| \endtable |
| |
| \section2 The Static QAccessible Functions |
| |
| The accessibility is managed by QAccessible's static functions, |
| which we will examine shortly. They produce QAccessible |
| interfaces, build the object tree, and initiate the connection |
| with MSAA or the other platform specific technologies. If you are |
| only interested in learning how to make your application |
| accessible, you can safely skip over this section to |
| \l{Implementing Accessibility}. |
| |
| The communication between clients and the server is initiated when |
| \l{QAccessible::}{setRootObject()} is called. This is done when |
| the QApplication instance is instantiated and you should not have |
| to do this yourself. |
| |
| When a QObject calls \l{QAccessible::}{updateAccessibility()}, |
| clients that are listening to events are notified of the |
| change. The function is used to post events to the assistive |
| technology, and accessible \l{QAccessible::Event}{events} are |
| posted by \l{QAccessible::}{updateAccessibility()}. |
| |
| \l{QAccessible::}{queryAccessibleInterface()} returns accessible |
| interfaces for \l{QObject}s. All widgets in Qt provide interfaces; |
| if you need interfaces to control the behavior of other \l{QObject} |
| subclasses, you must implement the interfaces yourself, although |
| the QAccessibleObject convenience class implements parts of the |
| functionality for you. |
| |
| The factory that produces accessibility interfaces for QObjects is |
| a function of type QAccessible::InterfaceFactory. It is possible |
| to have several factories installed. The last factory installed |
| will be the first to be asked for interfaces. |
| \l{QAccessible::}{queryAccessibleInterface()} uses the factories |
| to create interfaces for \l{QObject}s. Normally, you need not be |
| concerned about factories because you can implement plugins that |
| produce interfaces. We will give examples of both approaches |
| later. |
| |
| \section1 Implementing Accessibility |
| |
| To provide accessibility support for a widget or other user |
| interface element, you need to implement the QAccessibleInterface |
| and distribute it in a QAccessiblePlugin. It is also possible to |
| compile the interface into the application and provide a |
| QAccessible::InterfaceFactory for it. The factory can be used if |
| you link statically or do not want the added complexity of |
| plugins. This can be an advantage if you, for instance, are |
| delivering a 3-rd party library. |
| |
| All widgets and other user interface elements should have |
| interfaces and plugins. If you want your application to support |
| accessibility, you will need to consider the following: |
| |
| \list |
| \li Qt already implements accessibility for its own widgets. |
| We therefore recommend that you use Qt widgets where possible. |
| \li A QAccessibleInterface needs to be implemented for each element |
| that you want to make available to accessibility clients. |
| \li You need to send accessibility events from the custom |
| user interface elements that you implement. |
| \endlist |
| |
| In general, it is recommended that you are somewhat familiar with |
| MSAA, which Qt's accessibility support originally was built for. |
| You should also study the enum values of QAccessible, which |
| describe the roles, actions, relationships, and events that you |
| need to consider. |
| |
| Note that you can examine how Qt's widgets implement their |
| accessibility. One major problem with the MSAA standard is that |
| interfaces are often implemented in an inconsistent way. This |
| makes life difficult for clients and often leads to guesswork on |
| object functionality. |
| |
| It is possible to implement interfaces by inheriting |
| QAccessibleInterface and implementing its pure virtual functions. |
| In practice, however, it is usually preferable to inherit |
| QAccessibleObject or QAccessibleWidget, which implement part of |
| the functionality for you. In the next section, we will see an |
| example of implementing accessibility for a widget by inheriting |
| the QAccessibleWidget class. |
| |
| \section2 The QAccessibleObject and QAccessibleWidget Convenience Classes |
| |
| When implementing an accessibility interface for widgets, one would |
| as a rule inherit QAccessibleWidget, which is a convenience class |
| for widgets. Another available convenience class, which is |
| inherited by QAccessibleWidget, is the QAccessibleObject, which |
| implements part of the interface for QObjects. |
| |
| The QAccessibleWidget provides the following functionality: |
| |
| \list |
| \li It handles the navigation of the tree and |
| hit testing of the objects. |
| \li It handles events, roles, and actions that are common for all |
| \l{QWidget}s. |
| \li It handles action and methods that can be performed on |
| all widgets. |
| \li It calculates bounding rectangles with |
| \l{QAccessibleInterface::}{rect()}. |
| \li It gives \l{QAccessibleInterface::}{text()} strings that are |
| appropriate for a generic widget. |
| \li It sets the \l{QAccessible::State}{states} that |
| are common for all widgets. |
| \endlist |
| |
| \section2 QAccessibleWidget Example |
| |
| Instead of creating a custom widget and implementing an interface |
| for it, we will show how accessibility is implemented for one of |
| Qt's standard widgets: QSlider. The accessible interface, |
| QAccessibleSlider, inherits from QAccessibleAbstractSlider, which |
| in turn inherits QAccessibleWidget. You do not need to examine the |
| QAccessibleAbstractSlider class to read this section. If you want |
| to take a look, the code for all of Qt's accessible interfaces are |
| found in qtbase/src/widgets/accessible. Here is the |
| QAccessibleSlider's constructor: |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 0 |
| |
| The slider is a complex control that functions as a |
| \l{QAccessible::}{Controller} for its accessible children. |
| This relationship must be known by the interface (for |
| \l{QAccessibleInterface::}{parent()}, \l{QAccessibleInterface::}{child()} and |
| \l{QAccessibleInterface::}{relations()}). This can be done |
| using a controlling signal, which is a mechanism provided by |
| QAccessibleWidget. We do this in the constructor: |
| |
| The choice of signal shown is not important; the same principles |
| apply to all signals that are declared in this way. Note that we |
| use QLatin1String to ensure that the signal name is correctly |
| specified. |
| |
| When an accessible object is changed in a way that users need |
| to know about, it notifies clients of the change by sending them |
| an event via the accessible interface. This is how QSlider calls |
| \l{QAccessible::}{updateAccessibility()} to indicate that |
| its value has changed: |
| |
| \snippet snippets/qabstractsliderisnippet.cpp 0 |
| \dots |
| \snippet snippets/qabstractsliderisnippet.cpp 1 |
| \dots |
| \snippet snippets/qabstractsliderisnippet.cpp 2 |
| |
| Note that the call is made after the value of the slider has |
| changed because clients may query the new value immediately after |
| receiving the event. |
| |
| The interface must be able to calculate bounding rectangles of |
| itself and any children that do not provide an interface of their |
| own. The \c QAccessibleSlider has three such children identified by |
| the private enum, \c SliderElements, which has the following values: |
| \c PageLeft (the rectangle on the left hand side of the slider |
| handle), \c PageRight (the rectangle on the right hand side of the |
| handle), and \c Position (the slider handle). Here is the |
| implementation of \l{QAccessibleInterface::}{rect()}: |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 1 |
| \dots |
| \snippet snippets/accessibilityslidersnippet.cpp 2 |
| \dots |
| |
| The first part of the function, which we have omitted, uses the |
| current \l{QStyle}{style} to calculate the slider handle's |
| bounding rectangle; it is stored in \c srect. Notice that child 0, |
| covered in the default case in the above code, is the slider itself, |
| so we can simply return the QSlider bounding rectangle obtained |
| from the superclass, which is effectively the value obtained from |
| QAccessibleWidget::rect(). |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 3 |
| |
| Before the rectangle is returned it must be mapped to screen |
| coordinates. |
| |
| The QAccessibleSlider must reimplement |
| QAccessibleInterface::childCount() since it manages children |
| without interfaces. |
| |
| The \l{QAccessibleInterface::}{text()} function returns the |
| QAccessible::Text strings for the slider: |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 4 |
| |
| The \c slider() function returns a pointer to the interface's |
| QSlider. Some values are left for the superclass's implementation. |
| Not all values are appropriate for all accessible objects, as you |
| can see for QAccessible::Value case. You should just return an |
| empty string for those values where no relevant text can be |
| provided. |
| |
| The implementation of the \l{QAccessibleInterface::}{role()} |
| function is straightforward: |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 5 |
| |
| The role function should be reimplemented by all objects and |
| describes the role of themselves and the children that do not |
| provide accessible interfaces of their own. |
| |
| Next, the accessible interface needs to return the |
| \l{QAccessible::State}{states} that the slider can be in. We look |
| at parts of the \c state() implementation to show how just a few |
| of the states are handled: |
| |
| \snippet snippets/accessibilityslidersnippet.cpp 6 |
| \dots |
| \snippet snippets/accessibilityslidersnippet.cpp 7 |
| |
| The superclass implementation of |
| \l{QAccessibleInterface::}{state()}, uses the |
| QAccessibleInterface::state() implementation. We simply need to |
| disable the buttons if the slider is at its minimum or maximum. |
| |
| We have now exposed the information we have about the slider to |
| the clients. For the clients to be able to alter the slider - for |
| example, to change its value - we must provide information about |
| the actions that can be performed and perform them upon request. |
| We discuss this in the next section. |
| |
| \section2 Handling Action Requests from Clients |
| |
| Applications can expose actions, which can be invoked by the |
| client. |
| In order to support actions in an object, inherit the |
| \l {QAccessibleActionInterface}. |
| |
| Interactive elements should expose functionality triggered |
| by mouse interaction, for example. |
| A button should, for example, implement a click action. |
| |
| Setting the focus is another action that should be implemented |
| for widgets that accept receive the focus. |
| |
| You need to re-implement \l{QAccessibleActionInterface::}{actionNames()} |
| to return a list of all actions that the object supports. |
| This list should not be localized. |
| |
| There are two functions that give information about the actions |
| that must return localized strings: |
| \l{QAccessibleActionInterface::}{localizedActionName()} and |
| \l{QAccessibleActionInterface::}{localizedActionDescription()}. |
| These functions can be used by the client to present the actions to the user. |
| In general, the name should be concise and only consist of a single word, such as "press". |
| |
| There is a list of standard action names and localizations available |
| that should be used when the action fits. This makes it easier for |
| clients to understand the semantics, and Qt will try to expose them |
| correctly on the different platforms. |
| |
| Of course the action also needs a way to be triggered. |
| \l{QAccessibleActionInterface::}{doAction()} should |
| invoke the action as advertised by name and description. |
| |
| To see examples on how to implement actions and methods, you |
| could examine the implementations for Qt's standard widgets such as |
| QAccessiblePushButton. |
| |
| \section2 Implementing Accessible Plugins |
| |
| In this section we will explain the procedure of implementing |
| accessible plugins for your interfaces. A plugin is a class stored |
| in a shared library that can be loaded at run-time. It is |
| convenient to distribute interfaces as plugins since they will only |
| be loaded when required. |
| |
| Creating an accessible plugin is achieved by inheriting QAccessiblePlugin, |
| defining the supported class names in the plugin's JSON description and |
| reimplementing \l{QAccessiblePlugin::}{create()} from QAccessiblePlugin. |
| The \c .pro file must be altered to use the |
| plugin template, and the library containing the plugin must be |
| placed on a path where Qt searches for accessible plugins. |
| |
| We will go through the implementation of \c SliderPlugin, which is |
| an accessible plugin that produces the QAccessibleSlider interface |
| from the \l{QAccessibleWidget Example}. We start with the \c key() |
| function: |
| |
| \snippet snippets/accessibilitypluginsnippet.cpp 0 |
| |
| We simply need to return the class name of the single interface |
| our plugin can create an accessible interface for. A plugin |
| can support any number of classes; just add more class names |
| to the string list. We move on to the \c create() function: |
| |
| \snippet snippets/accessibilitypluginsnippet.cpp 1 |
| |
| We check whether the interface requested is for QSlider; if it is, |
| we create and return an interface for it. Note that \c object will |
| always be an instance of \c classname. You must return 0 if you do |
| not support the class. \l{QAccessible::}{updateAccessibility()} |
| checks with the available accessibility plugins until it finds one |
| that does not return 0. |
| |
| Finally, you need to include macros in the cpp file: |
| |
| \snippet snippets/accessibilitypluginsnippet.cpp 2 |
| |
| The Q_PLUGIN_METADATA macro exports the plugin in the \c |
| SliderPlugin class into the \c acc_sliderplugin library. The first |
| argument is the plugins IID and the second is an optional json file |
| which holds metadata information for the plugin. For more |
| information on plugins, you can consult the plugins \l{How to |
| Create Qt Plugins}{overview document}. |
| |
| It does not matter if you need the plugin to be statically or |
| dynamically linked with the application. |
| |
| \section2 Implementing Interface Factories |
| |
| If you do not want to provide plugins for your accessibility |
| interfaces, you can use an interface factory |
| (QAccessible::InterfaceFactory), which is the recommended way to |
| provide accessible interfaces in a statically-linked application. |
| |
| A factory is a function pointer for a function that takes the same |
| parameters as \l{QAccessiblePlugin}'s |
| \l{QAccessiblePlugin::}{create()} - a QString and a QObject. It |
| also works the same way. You install the factory with the |
| \l{QAccessible::}{installFactory()} function. We give an example |
| of how to create a factory for the \c QAccessibleSlider interface: |
| |
| \snippet snippets/accessibilityfactorysnippet.cpp 0 |
| \dots |
| \snippet snippets/accessibilityfactorysnippet.cpp 1 |
| |
| \omit |
| |
| \section1 Implementing Bridges for Other Assistive Technologies |
| |
| An accessibility bridge provides the means for an assistive |
| technology to talk to Qt. On Windows and Mac, the built-in bridges |
| will be used. On UNIX, however, there are no built-in standard |
| assistive technology, and it might therefore be necessary to |
| implement an accessible bridge. |
| |
| A bridge is implemented by inheriting QAccessibleBridge for the |
| technology to support. The class defines the interface that Qt |
| needs an assistive technology to support: |
| |
| \list |
| \li A root object. This is the root in the accessible |
| object tree and is of type QAccessibleInterface. |
| \li Receive events from from accessible objects. |
| \endlist |
| |
| The root object is set with the |
| \l{QAccessibleBridge::}{setRootObject()}. In the case of Qt, this |
| will always be an interface for the QApplication instance of the |
| application. |
| |
| Event notification is sent through |
| \l{QAccessibleBridge::}{notifyAccessibilityUpdate()}. This |
| function is called by \l{QAccessible::}{updateAccessibility()}. Even |
| though the bridge needs only to implement these two functions, it |
| must be able to communicate the entire QAccessibleInterface to the |
| underlying technology. How this is achieved is, naturally, up to |
| the individual bridge and none of Qt's concern. |
| |
| As with accessible interfaces, you distribute accessible bridges |
| in plugins. Accessible bridge plugins are subclasses of the |
| QAccessibleBridgePlugin class; the class defines the functions |
| \l{QAccessibleBridgePlugin::}{create()} and |
| \l{QAccessibleBridgePlugin::}{keys()}, which must me |
| reimplemented. If Qt finds a built-in bridge to use, it will |
| ignore any available plugins. |
| |
| \endomit |
| |
| */ |
| |
| /*! |
| \page accessible-qtquick.html |
| \title Accessibility for Qt Quick Applications |
| \brief How to make your applications accessible to those with disabilities. |
| \startpage Accessibility |
| \previouspage Accessibility for QWidget Applications |
| |
| \ingroup best-practices |
| |
| \tableofcontents |
| |
| \section1 Introduction |
| |
| We will explain how to make Qt Quick applications accessible. |
| This can be compared to making web application accessible. |
| You simply need to assign a few properties when creating controls such |
| as buttons in QML. |
| |
| The most important property for this purpose is the attached property |
| \l {Accessible}. |
| |
| |
| */ |