source: trunk/doc/src/frameworks-technologies/accessible.qdoc@ 568

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 26.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \group accessibility
44 \title Accessibility Classes
45*/
46
47/*!
48 \page accessible.html
49 \title Accessibility
50
51 \ingroup frameworks-technologies
52
53 \tableofcontents
54
55 \section1 Introduction
56
57 Accessibility in computer software is making applications usable
58 for people with disabilities. This could be achieved by providing
59 keyboard shortcuts, a high-contrast user interface that uses
60 specially selected colors and fonts, or support for assistive tools
61 such as screen readers and braille displays.
62
63 An application does not usually communicate directly with
64 assistive tools but through an assistive technology, which is a
65 bridge for exchange of information between the applications and
66 the tools. Information about user interface elements, such
67 as buttons and scroll bars, is exposed to the assistive technologies.
68 Qt supports Microsoft Active Accessibility (MSAA) on Windows and
69 Mac OS X Accessibility on Mac OS X.
70 On Unix/X11, support is preliminary. The individual technologies
71 are abstracted from Qt, and there is only a single interface to
72 consider. We will use MSAA throughout this document when we need
73 to address technology related issues.
74
75 In this overview document, we will examine the overall Qt
76 accessibility architecture, and how to implement accessibility for
77 custom widgets and elements.
78
79 \section1 Architecture
80
81 Providing accessibility is a collaboration between accessibility
82 compliant applications, the assistive technology, and the
83 assistive tools.
84
85 \image accessibilityarchitecture.png
86
87 Accessibility compliant applications are called AT-Servers while
88 assistive tools are called AT-Clients. A Qt application will
89 typically be an AT-Server, but specialized programs might also
90 function like AT-Clients. We will refer to clients and servers
91 when talking about AT-Clients and AT-Servers in the rest of this
92 document.
93
94 We will from now on focus on the Qt accessibility interface and
95 how it is implemented to create Qt applications that support
96 accessibility.
97
98 \section2 Accessibility in Qt
99
100 These classes provide support for accessible applications.
101
102 \annotatedlist accessibility
103
104 When we communicate with the assistive technologies, we need to
105 describe Qt's user interface in a way that they can understand. Qt
106 applications use QAccessibleInterface to expose information about the
107 individual UI elements. Currently, Qt provides support for its widgets
108 and widget parts, e.g., slider handles, but the interface could
109 also be implemented for any QObject if necessary. QAccessible
110 contains enums that describe the UI. The description is mainly
111 based on MSAA and is independent of Qt. We will examine the enums
112 in the course of this document.
113
114 The structure of the UI is represented as a tree of
115 QAccessibleInterface subclasses. You can think of this as a
116 representation of a UI like the QObject tree built by Qt. Objects
117 can be widgets or widget parts (such as scroll bar handles). We
118 examine the tree in detail in the next section.
119
120 Servers notify clients through \l{QAccessible::}{updateAccessibility()}
121 about changes in objects by sending events, and the clients
122 register to receive the events. The available events are defined
123 by the QAccessible::Event enum. The clients may then query for
124 the object that generated the event through
125 QAccessible::queryAccessibleInterface().
126
127 Three of the enums in QAccessible help clients query and alter
128 accessible objects:
129
130 \list
131 \o \l{QAccessible::}{Role}: Describes the role the object
132 fills in the user interface, e.g., if it is a main
133 window, a text caret, or a cell in an item view.
134 \o \l{QAccessible::}{Action}: The actions that the
135 clients can perform on the objects, e.g., pushing a
136 button.
137 \o \l{QAccessible::}{Relation}: Describes the relationship
138 between objects in the object tree.
139 This is used for navigation.
140 \endlist
141
142 The clients also have some possibilities to get the content of
143 objects, e.g., a button's text; the object provides strings
144 defined by the QAccessible::Text enum, that give information
145 about content.
146
147 The objects can be in a number of different states as defined by
148 the \l{QAccessible::}{State} enum. Examples of states are whether
149 the object is disabled, if it has focus, or if it provides a pop-up
150 menu.
151
152 \section2 The Accessible Object Tree
153
154 As mentioned, a tree structure is built from the accessible
155 objects of an application. By navigating through the tree, the
156 clients can access all elements in the UI. Object relations give
157 clients information about the UI. For instance, a slider handle is
158 a child of the slider to which it belongs. QAccessible::Relation
159 describes the various relationships the clients can ask objects
160 for.
161
162 Note that there are no direct mapping between the Qt QObject tree
163 and the accessible object tree. For instance, scroll bar handles
164 are accessible objects but are not widgets or objects in Qt.
165
166 AT-Clients have access to the accessibility object tree through
167 the root object in the tree, which is the QApplication. They can
168 query other objects through QAccessible::navigate(), which fetches
169 objects based on \l{QAccessible::}{Relation}s. The children of any
170 node is 1-based numbered. The child numbered 0 is the object
171 itself. The children of all interfaces are numbered this way,
172 i.e., it is not a fixed numbering from the root node in the entire
173 tree.
174
175 Qt provides accessible interfaces for its widgets. Interfaces for
176 any QObject subclass can be requested through
177 QAccessible::queryInterface(). A default implementation is
178 provided if a more specialized interface is not defined. An
179 AT-Client cannot acquire an interface for accessible objects that
180 do not have an equivalent QObject, e.g., scroll bar handles, but
181 they appear as normal objects through interfaces of parent
182 accessible objects, e.g., you can query their relationships with
183 QAccessible::relationTo().
184
185 To illustrate, we present an image of an accessible object tree.
186 Beneath the tree is a table with examples of object relationships.
187
188 \image accessibleobjecttree.png
189
190 The labels in top-down order are: the QAccessibleInterface class
191 name, the widget for which an interface is provided, and the
192 \l{QAccessible::}{Role} of the object. The Position, PageLeft and
193 PageRight correspond to the slider handle, the slider groove left
194 and the slider groove right, respectively. These accessible objects
195 do not have an equivalent QObject.
196
197 \table 40%
198 \header
199 \o Source Object
200 \o Target Object
201 \o Relation
202 \row
203 \o Slider
204 \o Indicator
205 \o Controller
206 \row
207 \o Indicator
208 \o Slider
209 \o Controlled
210 \row
211 \o Slider
212 \o Application
213 \o Ancestor
214 \row
215 \o Application
216 \o Slider
217 \o Child
218 \row
219 \o PushButton
220 \o Indicator
221 \o Sibling
222 \endtable
223
224 \section2 The Static QAccessible Functions
225
226 The accessibility is managed by QAccessible's static functions,
227 which we will examine shortly. They produce QAccessible
228 interfaces, build the object tree, and initiate the connection
229 with MSAA or the other platform specific technologies. If you are
230 only interested in learning how to make your application
231 accessible, you can safely skip over this section to
232 \l{Implementing Accessibility}.
233
234 The communication between clients and the server is initiated when
235 \l{QAccessible::}{setRootObject()} is called. This is done when
236 the QApplication instance is instantiated and you should not have
237 to do this yourself.
238
239 When a QObject calls \l{QAccessible::}{updateAccessibility()},
240 clients that are listening to events are notified of the
241 change. The function is used to post events to the assistive
242 technology, and accessible \l{QAccessible::Event}{events} are
243 posted by \l{QAccessible::}{updateAccessibility()}.
244
245 \l{QAccessible::}{queryAccessibleInterface()} returns accessible
246 interfaces for \l{QObject}s. All widgets in Qt provide interfaces;
247 if you need interfaces to control the behavior of other \l{QObject}
248 subclasses, you must implement the interfaces yourself, although
249 the QAccessibleObject convenience class implements parts of the
250 functionality for you.
251
252 The factory that produces accessibility interfaces for QObjects is
253 a function of type QAccessible::InterfaceFactory. It is possible
254 to have several factories installed. The last factory installed
255 will be the first to be asked for interfaces.
256 \l{QAccessible::}{queryAccessibleInterface()} uses the factories
257 to create interfaces for \l{QObject}s. Normally, you need not be
258 concerned about factories because you can implement plugins that
259 produce interfaces. We will give examples of both approaches
260 later.
261
262 \section2 Enabling Accessibility Support
263
264 By default, Qt applications are run with accessibility support
265 enabled on Windows and Mac OS X. On Unix/X11 platforms, applications
266 must be launched in an environment with the \c QT_ACCESSIBILITY
267 variable set to 1. For example, this is set in the following way with
268 the bash shell:
269
270 \snippet doc/src/snippets/code/doc_src_qt4-accessibility.qdoc environment
271
272 Accessibility features are built into Qt by default when the libraries
273 are configured and built.
274
275 \section1 Implementing Accessibility
276
277 To provide accessibility support for a widget or other user
278 interface element, you need to implement the QAccessibleInterface
279 and distribute it in a QAccessiblePlugin. It is also possible to
280 compile the interface into the application and provide a
281 QAccessible::InterfaceFactory for it. The factory can be used if
282 you link statically or do not want the added complexity of
283 plugins. This can be an advantage if you, for instance, are
284 delivering a 3-rd party library.
285
286 All widgets and other user interface elements should have
287 interfaces and plugins. If you want your application to support
288 accessibility, you will need to consider the following:
289
290 \list
291 \o Qt already implements accessibility for its own widgets.
292 We therefore recommend that you use Qt widgets where possible.
293 \o A QAccessibleInterface needs to be implemented for each element
294 that you want to make available to accessibility clients.
295 \o You need to send accessibility events from the custom
296 user interface elements that you implement.
297 \endlist
298
299 In general, it is recommended that you are somewhat familiar with
300 MSAA, which Qt's accessibility support originally was built for.
301 You should also study the enum values of QAccessible, which
302 describe the roles, actions, relationships, and events that you
303 need to consider.
304
305 Note that you can examine how Qt's widgets implement their
306 accessibility. One major problem with the MSAA standard is that
307 interfaces are often implemented in an inconsistent way. This
308 makes life difficult for clients and often leads to guesswork on
309 object functionality.
310
311 It is possible to implement interfaces by inheriting
312 QAccessibleInterface and implementing its pure virtual functions.
313 In practice, however, it is usually preferable to inherit
314 QAccessibleObject or QAccessibleWidget, which implement part of
315 the functionality for you. In the next section, we will see an
316 example of implementing accessibility for a widget by inheriting
317 the QAccessibleWidget class.
318
319 \section2 The QAccessibleObject and QAccessibleWidget Convenience Classes
320
321 When implementing an accessibility interface for widgets, one would
322 as a rule inherit QAccessibleWidget, which is a convenience class
323 for widgets. Another available convenience class, which is
324 inherited by QAccessibleWidget, is the QAccessibleObject, which
325 implements part of the interface for QObjects.
326
327 The QAccessibleWidget provides the following functionality:
328
329 \list
330 \o It handles the navigation of the tree and
331 hit testing of the objects.
332 \o It handles events, roles, and actions that are common for all
333 \l{QWidget}s.
334 \o It handles action and methods that can be performed on
335 all widgets.
336 \o It calculates bounding rectangles with
337 \l{QAccessibleInterface::}{rect()}.
338 \o It gives \l{QAccessibleInterface::}{text()} strings that are
339 appropriate for a generic widget.
340 \o It sets the \l{QAccessible::State}{states} that
341 are common for all widgets.
342 \endlist
343
344 \section2 QAccessibleWidget Example
345
346 Instead of creating a custom widget and implementing an interface
347 for it, we will show how accessibility can be implemented for one of
348 Qt's standard widgets: QSlider. Making this widget accessible
349 demonstrates many of the issues that need to be faced when making
350 a custom widget accessible.
351
352 The slider is a complex control that functions as a
353 \l{QAccessible::}{Controller} for its accessible children.
354 This relationship must be known by the interface (for
355 \l{QAccessibleInterface::}{relationTo()} and
356 \l{QAccessibleInterface::}{navigate()}). This can be done
357 using a controlling signal, which is a mechanism provided by
358 QAccessibleWidget. We do this in the constructor:
359
360 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 0
361
362 The choice of signal shown is not important; the same principles
363 apply to all signals that are declared in this way. Note that we
364 use QLatin1String to ensure that the signal name is correctly
365 specified.
366
367 When an accessible object is changed in a way that users need
368 to know about, it notifies clients of the change by sending them
369 an event via the accessible interface. This is how QSlider calls
370 \l{QAccessibleInterface::}{updateAccessibility()} to indicate that
371 its value has changed:
372
373 \snippet doc/src/snippets/qabstractsliderisnippet.cpp 0
374 \dots
375 \snippet doc/src/snippets/qabstractsliderisnippet.cpp 1
376 \dots
377 \snippet doc/src/snippets/qabstractsliderisnippet.cpp 2
378
379 Note that the call is made after the value of the slider has
380 changed because clients may query the new value immediately after
381 receiving the event.
382
383 The interface must be able to calculate bounding rectangles of
384 itself and any children that do not provide an interface of their
385 own. The \c QAccessibleSlider has three such children identified by
386 the private enum, \c SliderElements, which has the following values:
387 \c PageLeft (the rectangle on the left hand side of the slider
388 handle), \c PageRight (the rectangle on the right hand side of the
389 handle), and \c Position (the slider handle). Here is the
390 implementation of \l{QAccessibleInterface::}{rect()}:
391
392 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 1
393 \dots
394 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 2
395 \dots
396
397 The first part of the function, which we have omitted, uses the
398 current \l{QStyle}{style} to calculate the slider handle's
399 bounding rectangle; it is stored in \c srect. Notice that child 0,
400 covered in the default case in the above code, is the slider itself,
401 so we can simply return the QSlider bounding rectangle obtained
402 from the superclass, which is effectively the value obtained from
403 QAccessibleWidget::rect().
404
405 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 3
406
407 Before the rectangle is returned it must be mapped to screen
408 coordinates.
409
410 The QAccessibleSlider must reimplement
411 QAccessibleInterface::childCount() since it manages children
412 without interfaces.
413
414 The \l{QAccessibleInterface::}{text()} function returns the
415 QAccessible::Text strings for the slider:
416
417 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 4
418
419 The \c slider() function returns a pointer to the interface's
420 QSlider. Some values are left for the superclass's implementation.
421 Not all values are appropriate for all accessible objects, as you
422 can see for QAccessible::Value case. You should just return an
423 empty string for those values where no relevant text can be
424 provided.
425
426 The implementation of the \l{QAccessibleInterface::}{role()}
427 function is straightforward:
428
429 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 5
430
431 The role function should be reimplemented by all objects and
432 describes the role of themselves and the children that do not
433 provide accessible interfaces of their own.
434
435 Next, the accessible interface needs to return the
436 \l{QAccessible::State}{states} that the slider can be in. We look
437 at parts of the \c state() implementation to show how just a few
438 of the states are handled:
439
440 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 6
441 \dots
442 \snippet doc/src/snippets/accessibilityslidersnippet.cpp 7
443
444 The superclass implementation of
445 \l{QAccessibleInterface::}{state()}, uses the
446 QAccessibleInterface::state() implementation. We simply need to
447 disable the buttons if the slider is at its minimum or maximum.
448
449 We have now exposed the information we have about the slider to
450 the clients. For the clients to be able to alter the slider - for
451 example, to change its value - we must provide information about
452 the actions that can be performed and perform them upon request.
453 We discuss this in the next section.
454
455 \section2 Handling Action Requests from Clients
456
457 QAccessible provides a number of \l{QAccessible::}{Action}s
458 that can be performed on request from clients. If an
459 accessible object supports actions, it should reimplement the
460 following functions from QAccessibleInterface:
461
462 \list
463 \o \l{QAccessibleInterface::}{actionText()} returns
464 strings that describe each action. The descriptions
465 to be made available are one for each
466 \l{QAccessible::}{Text} enum value.
467 \o \l{QAccessibleInterface::}{doAction()} executes requests
468 from clients to perform actions.
469 \endlist
470
471 Note that a client can request any action from an object. If
472 the object does not support the action, it returns false from
473 \l{QAccessibleInterface::}{doAction()}.
474
475 None of the standard actions take any parameters. It is possible
476 to provide user-defined actions that can take parameters.
477 The interface must then also reimplement
478 \l{QAccessibleInterface::}{userActionCount()}. Since this is not
479 defined in the MSAA specification, it is probably only useful to
480 use this if you know which specific AT-Clients will use the
481 application.
482
483 QAccessibleInterface gives another technique for clients to handle
484 accessible objects. It works basically the same way, but uses the
485 concept of methods in place of actions. The available methods are
486 defined by the QAccessible::Method enum. The following functions
487 need to be reimplemented from QAccessibleInterface if the
488 accessible object is to support methods:
489
490 \list
491 \o \l{QAccessibleInterface::}{supportedMethods()} returns
492 a QSet of \l{QAccessible::}{Method} values that are
493 supported by the object.
494 \o \l{QAccessibleInterface::}{invokeMethod()} executes
495 methods requested by clients.
496 \endlist
497
498 The action mechanism will probably be substituted by providing
499 methods in place of the standard actions.
500
501 To see examples on how to implement actions and methods, you
502 could examine the QAccessibleObject and QAccessibleWidget
503 implementations. You might also want to take a look at the
504 MSAA documentation.
505
506 \section2 Implementing Accessible Plugins
507
508 In this section we will explain the procedure of implementing
509 accessible plugins for your interfaces. A plugin is a class stored
510 in a shared library that can be loaded at run-time. It is
511 convenient to distribute interfaces as plugins since they will only
512 be loaded when required.
513
514 Creating an accessible plugin is achieved by inheriting
515 QAccessiblePlugin, reimplementing \l{QAccessiblePlugin::}{keys()}
516 and \l{QAccessiblePlugin::}{create()} from that class, and adding
517 one or two macros. The \c .pro file must be altered to use the
518 plugin template, and the library containing the plugin must be
519 placed on a path where Qt searches for accessible plugins.
520
521 We will go through the implementation of \c SliderPlugin, which is an
522 accessible plugin that produces interfaces for the
523 QAccessibleSlider we implemented in the \l{QAccessibleWidget Example}.
524 We start with the \c key() function:
525
526 \snippet doc/src/snippets/accessibilitypluginsnippet.cpp 0
527
528 We simply need to return the class name of the single interface
529 our plugin can create an accessible interface for. A plugin
530 can support any number of classes; just add more class names
531 to the string list. We move on to the \c create() function:
532
533 \snippet doc/src/snippets/accessibilitypluginsnippet.cpp 1
534
535 We check whether the interface requested is for the QSlider; if it
536 is, we create and return an interface for it. Note that \c object
537 will always be an instance of \c classname. You must return 0 if
538 you do not support the class.
539 \l{QAccessible::}{updateAccessibility()} checks with the
540 available accessibility plugins until it finds one that does not
541 return 0.
542
543 Finally, you need to include macros in the cpp file:
544
545 \snippet doc/src/snippets/accessibilitypluginsnippet.cpp 2
546
547 The Q_EXPORT_PLUGIN2 macro exports the plugin in the \c
548 SliderPlugin class into the \c acc_sliderplugin library. The first
549 argument is the name of the plugin library file, excluding the
550 file suffix, and the second is the class name. For more information
551 on plugins, consult the plugins \l{How to Create Qt
552 Plugins}{overview document}.
553
554 You can omit the first macro unless you want the plugin
555 to be statically linked with the application.
556
557 \section2 Implementing Interface Factories
558
559 If you do not want to provide plugins for your accessibility
560 interfaces, you can use an interface factory
561 (QAccessible::InterfaceFactory), which is the recommended way to
562 provide accessible interfaces in a statically-linked application.
563
564 A factory is a function pointer for a function that takes the same
565 parameters as \l{QAccessiblePlugin}'s
566 \l{QAccessiblePlugin::}{create()} - a QString and a QObject. It
567 also works the same way. You install the factory with the
568 \l{QAccessible::}{installFactory()} function. We give an example
569 of how to create a factory for the \c SliderPlugin class:
570
571 \snippet doc/src/snippets/accessibilityfactorysnippet.cpp 0
572 \dots
573 \snippet doc/src/snippets/accessibilityfactorysnippet.cpp 1
574
575 \omit
576
577 \section1 Implementing Bridges for Other Assistive Technologies
578
579 An accessibility bridge provides the means for an assistive
580 technology to talk to Qt. On Windows and Mac, the built-in bridges
581 will be used. On UNIX, however, there are no built-in standard
582 assistive technology, and it might therefore be necessary to
583 implement an accessible bridge.
584
585 A bridge is implemented by inheriting QAccessibleBridge for the
586 technology to support. The class defines the interface that Qt
587 needs an assistive technology to support:
588
589 \list
590 \o A root object. This is the root in the accessible
591 object tree and is of type QAccessibleInterface.
592 \o Receive events from from accessible objects.
593 \endlist
594
595 The root object is set with the
596 \l{QAccessibleBridge::}{setRootObject()}. In the case of Qt, this
597 will always be an interface for the QApplication instance of the
598 application.
599
600 Event notification is sent through
601 \l{QAccessibleBridge::}{notifyAccessibilityUpdate()}. This
602 function is called by \l{QAccessible::}{updateAccessibility()}. Even
603 though the bridge needs only to implement these two functions, it
604 must be able to communicate the entire QAccessibleInterface to the
605 underlying technology. How this is achieved is, naturally, up to
606 the individual bridge and none of Qt's concern.
607
608 As with accessible interfaces, you distribute accessible bridges
609 in plugins. Accessible bridge plugins are subclasses of the
610 QAccessibleBridgePlugin class; the class defines the functions
611 \l{QAccessibleBridgePlugin::}{create()} and
612 \l{QAccessibleBridgePlugin::}{keys()}, which must me
613 reimplemented. If Qt finds a built-in bridge to use, it will
614 ignore any available plugins.
615
616 \endomit
617
618 \section1 Further Reading
619
620 The \l{Cross-Platform Accessibility Support in Qt 4} document contains a more
621 general overview of Qt's accessibility features and discusses how it is
622 used on each platform.
623 issues
624*/
Note: See TracBrowser for help on using the repository browser.