/usr/share/qt5/doc/qtdoc/accessible-qwidget.html is in qt5-doc-html 5.5.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- accessible.qdoc -->
<title>Accessibility for QWidget Applications | Qt 5.5 </title>
<link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
<div class="main">
<div class="main-rounded">
<div class="navigationbar">
<ul>
<li><a href="index.html">Qt 5.5</a></li>
<li>Accessibility for QWidget Applications</li>
<li id="buildversion">Qt 5.5.1 Reference Documentation</li>
</ul>
</div>
</div>
<div class="content">
<div class="line">
<div class="content mainContent">
<link rel="prev" href="accessible.html" />
<link rel="next" href="accessible-qtquick.html" />
<p class="naviNextPrevious headerNavi">
<a class="prevPage" href="accessible.html">Accessibility</a>
<a class="nextPage" href="accessible-qtquick.html">Accessibility for Qt Quick Applications</a>
</p><p/>
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#introduction">Introduction</a></li>
<li class="level2"><a href="#accessibility-in-qwidget-based-applications">Accessibility in QWidget based applications</a></li>
<li class="level2"><a href="#the-accessible-object-tree">The Accessible Object Tree</a></li>
<li class="level2"><a href="#the-static-qaccessible-functions">The Static QAccessible Functions</a></li>
<li class="level1"><a href="#implementing-accessibility">Implementing Accessibility</a></li>
<li class="level2"><a href="#the-qaccessibleobject-and-qaccessiblewidget-convenience-classes">The QAccessibleObject and QAccessibleWidget Convenience Classes</a></li>
<li class="level2"><a href="#qaccessiblewidget-example">QAccessibleWidget Example</a></li>
<li class="level2"><a href="#handling-action-requests-from-clients">Handling Action Requests from Clients</a></li>
<li class="level2"><a href="#implementing-accessible-plugins">Implementing Accessible Plugins</a></li>
<li class="level2"><a href="#implementing-interface-factories">Implementing Interface Factories</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Accessibility for QWidget Applications</h1>
<span class="subtitle"></span>
<!-- $$$accessible-qwidget.html-description -->
<div class="descr"> <a name="details"></a>
<a name="introduction"></a>
<h2 id="introduction">Introduction</h2>
<p>We will focus on the Qt accessibility interface <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> and how to make applications accessible.</p>
<a name="accessibility-in-qwidget-based-applications"></a>
<h3 >Accessibility in QWidget based applications</h3>
<p>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 <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> 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 <a href="../qtcore/qobject.html">QObject</a> if necessary. <a href="../qtgui/qaccessible.html">QAccessible</a> contains enums that describe the UI. The description is mainly based on MSAA and is independent of Qt. We will examine the enums in the course of this document.</p>
<p>The structure of the UI is represented as a tree of <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> subclasses. You can think of this as a representation of a UI like the <a href="../qtcore/qobject.html">QObject</a> tree built by Qt. Objects can be widgets or widget parts (such as scroll bar handles). We examine the tree in detail in the next section.</p>
<p>Servers notify clients through <a href="../qtgui/qaccessible.html#updateAccessibility">updateAccessibility()</a> about changes in objects by sending events, and the clients register to receive the events. The available events are defined by the <a href="../qtgui/qaccessible.html#Event-enum">QAccessible::Event</a> enum. The clients may then query for the object that generated the event through <a href="../qtgui/qaccessible.html#queryAccessibleInterface">QAccessible::queryAccessibleInterface</a>().</p>
<p>The members and enums in <a href="../qtgui/qaccessible.html">QAccessible</a> are used to describe accessible objects:</p>
<ul>
<li><a href="../qtgui/qaccessible.html#Role-enum">Role</a>: 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>
<li><a href="../qtgui/qaccessible.html#RelationFlag-enum">Relation</a>: Describes the relationship between objects in the object hierarchy.</li>
<li><a href="../qtgui/qaccessible-state.html">State</a>: 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.</li>
</ul>
<p>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 <a href="../qtgui/qaccessible.html#Text-enum">QAccessible::Text</a> enum, that give information about content.</p>
<a name="the-accessible-object-tree"></a>
<h3 >The Accessible Object Tree</h3>
<p>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. <a href="../qtgui/qaccessible.html#RelationFlag-enum">QAccessible::Relation</a> describes the various relationships the clients can ask objects for.</p>
<p>Note that there are no direct mapping between the Qt <a href="../qtcore/qobject.html">QObject</a> tree and the accessible object tree. For instance, scroll bar handles are accessible objects but are not widgets or objects in Qt.</p>
<p>AT-Clients have access to the accessibility object tree through the root object in the tree, which is the <a href="../qtwidgets/qapplication.html">QApplication</a>. They can navigate the tree with the <a href="../qtgui/qaccessibleinterface.html#parent">QAccessibleInterface::parent</a>(), <a href="../qtgui/qaccessibleinterface.html#childCount">QAccessibleInterface::childCount</a>() and <a href="../qtgui/qaccessibleinterface.html#child">QAccessibleInterface::child</a>() functions.</p>
<p>Qt provides accessible interfaces for its widgets and for Qt Quick Controls. Interfaces for any <a href="../qtcore/qobject.html">QObject</a> 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 <a href="../qtcore/qobject.html">QObject</a>, 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 <a href="../qtgui/qaccessibleinterface.html#relations">QAccessibleInterface::relations</a>().</p>
<p>To illustrate, we present an image of an accessible object tree. Beneath the tree is a table with examples of object relationships.</p>
<p class="centerAlign"><img src="images/accessibleobjecttree.png" alt="" /></p><p>The labels in top-down order are: the <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> class name, the widget for which an interface is provided, and the <a href="../qtgui/qaccessible.html#Role-enum">Role</a> 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 <a href="../qtcore/qobject.html">QObject</a>.</p>
<div class="table"><table class="generic" width="40%">
<thead><tr class="qt-style"><th >Source Object</th><th >Target Object</th><th >Relation</th></tr></thead>
<tr valign="top" class="odd"><td >Slider</td><td >Indicator</td><td >Controller</td></tr>
<tr valign="top" class="even"><td >Indicator</td><td >Slider</td><td >Controlled</td></tr>
<tr valign="top" class="odd"><td >Slider</td><td >Application</td><td >Ancestor</td></tr>
<tr valign="top" class="even"><td >Application</td><td >Slider</td><td >Child</td></tr>
<tr valign="top" class="odd"><td >PushButton</td><td >Indicator</td><td >Sibling</td></tr>
</table></div>
<a name="the-static-qaccessible-functions"></a>
<h3 >The Static QAccessible Functions</h3>
<p>The accessibility is managed by <a href="../qtgui/qaccessible.html">QAccessible</a>'s static functions, which we will examine shortly. They produce <a href="../qtgui/qaccessible.html">QAccessible</a> 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 <a href="accessible-qwidget.html#implementing-accessibility">Implementing Accessibility</a>.</p>
<p>The communication between clients and the server is initiated when <a href="../qtgui/qaccessible.html#setRootObject">setRootObject()</a> is called. This is done when the <a href="../qtwidgets/qapplication.html">QApplication</a> instance is instantiated and you should not have to do this yourself.</p>
<p>When a <a href="../qtcore/qobject.html">QObject</a> calls <a href="../qtgui/qaccessible.html#updateAccessibility">updateAccessibility()</a>, clients that are listening to events are notified of the change. The function is used to post events to the assistive technology, and accessible <a href="../qtgui/qaccessible.html#Event-enum">events</a> are posted by <a href="../qtgui/qaccessible.html#updateAccessibility">updateAccessibility()</a>.</p>
<p><a href="../qtgui/qaccessible.html#queryAccessibleInterface">queryAccessibleInterface()</a> returns accessible interfaces for <a href="../qtcore/qobject.html">QObject</a>s. All widgets in Qt provide interfaces; if you need interfaces to control the behavior of other <a href="../qtcore/qobject.html">QObject</a> subclasses, you must implement the interfaces yourself, although the <a href="../qtgui/qaccessibleobject.html">QAccessibleObject</a> convenience class implements parts of the functionality for you.</p>
<p>The factory that produces accessibility interfaces for <a href="../qtwebkit/qtwebkit-bridge.html#qobjects">QObjects</a> is a function of type <a href="../qtgui/qaccessible.html#InterfaceFactory-typedef">QAccessible::InterfaceFactory</a>. It is possible to have several factories installed. The last factory installed will be the first to be asked for interfaces. <a href="../qtgui/qaccessible.html#queryAccessibleInterface">queryAccessibleInterface()</a> uses the factories to create interfaces for <a href="../qtcore/qobject.html">QObject</a>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.</p>
<a name="implementing-accessibility"></a>
<h2 id="implementing-accessibility">Implementing Accessibility</h2>
<p>To provide accessibility support for a widget or other user interface element, you need to implement the <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> and distribute it in a <a href="../qtgui/qaccessibleplugin.html">QAccessiblePlugin</a>. It is also possible to compile the interface into the application and provide a <a href="../qtgui/qaccessible.html#InterfaceFactory-typedef">QAccessible::InterfaceFactory</a> 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.</p>
<p>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:</p>
<ul>
<li>Qt already implements accessibility for its own widgets. We therefore recommend that you use Qt widgets where possible.</li>
<li>A <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> needs to be implemented for each element that you want to make available to accessibility clients.</li>
<li>You need to send accessibility events from the custom user interface elements that you implement.</li>
</ul>
<p>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 <a href="../qtgui/qaccessible.html">QAccessible</a>, which describe the roles, actions, relationships, and events that you need to consider.</p>
<p>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.</p>
<p>It is possible to implement interfaces by inheriting <a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a> and implementing its pure virtual functions. In practice, however, it is usually preferable to inherit <a href="../qtgui/qaccessibleobject.html">QAccessibleObject</a> or <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a>, 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 <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a> class.</p>
<a name="the-qaccessibleobject-and-qaccessiblewidget-convenience-classes"></a>
<h3 >The QAccessibleObject and QAccessibleWidget Convenience Classes</h3>
<p>When implementing an accessibility interface for widgets, one would as a rule inherit <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a>, which is a convenience class for widgets. Another available convenience class, which is inherited by <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a>, is the <a href="../qtgui/qaccessibleobject.html">QAccessibleObject</a>, which implements part of the interface for <a href="../qtwebkit/qtwebkit-bridge.html#qobjects">QObjects</a>.</p>
<p>The <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a> provides the following functionality:</p>
<ul>
<li>It handles the navigation of the tree and hit testing of the objects.</li>
<li>It handles events, roles, and actions that are common for all <a href="../qtwidgets/qwidget.html">QWidget</a>s.</li>
<li>It handles action and methods that can be performed on all widgets.</li>
<li>It calculates bounding rectangles with <a href="../qtgui/qaccessibleinterface.html#rect">rect()</a>.</li>
<li>It gives <a href="../qtgui/qaccessibleinterface.html#text">text()</a> strings that are appropriate for a generic widget.</li>
<li>It sets the <a href="../qtgui/qaccessible-state.html">states</a> that are common for all widgets.</li>
</ul>
<a name="qaccessiblewidget-example"></a>
<h3 >QAccessibleWidget Example</h3>
<p>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: <a href="../qtwidgets/qslider.html">QSlider</a>. The accessible interface, QAccessibleSlider, inherits from QAccessibleAbstractSlider, which in turn inherits <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a>. 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 src/plugins/accessible/widgets. Here is the QAccessibleSlider's constructor:</p>
<pre class="cpp"><span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span><span class="operator">::</span><span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span>(<span class="type"><a href="../qtwidgets/qwidget.html">QWidget</a></span> <span class="operator">*</span>w)
: <span class="type"><a href="../qtwidgets/qaccessibleabstractslider.html">QAccessibleAbstractSlider</a></span>(w)
{
Q_ASSERT(slider());
addControllingSignal(QLatin1String(<span class="string">"valueChanged(int)"</span>));
}</pre>
<p>The slider is a complex control that functions as a <a href="../qtgui/qaccessible.html#RelationFlag-enum">Controller</a> for its accessible children. This relationship must be known by the interface (for <a href="../qtgui/qaccessibleinterface.html#parent">parent()</a>, <a href="../qtgui/qaccessibleinterface.html#child">child()</a> and <a href="../qtgui/qaccessibleinterface.html#relations">relations()</a>). This can be done using a controlling signal, which is a mechanism provided by <a href="../qtwidgets/qaccessiblewidget.html">QAccessibleWidget</a>. We do this in the constructor:</p>
<p>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 <a href="../qtcore/qlatin1string.html">QLatin1String</a> to ensure that the signal name is correctly specified.</p>
<p>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 <a href="../qtwidgets/qslider.html">QSlider</a> calls <a href="../qtgui/qaccessible.html#updateAccessibility">updateAccessibility()</a> to indicate that its value has changed:</p>
<pre class="cpp"><span class="type">void</span> <span class="type"><a href="../qtwidgets/qabstractslider.html">QAbstractSlider</a></span><span class="operator">::</span>setValue(<span class="type">int</span> value)
...
<span class="type"><a href="../qtgui/qaccessiblevaluechangeevent.html">QAccessibleValueChangeEvent</a></span> event(<span class="keyword">this</span><span class="operator">,</span> d<span class="operator">-</span><span class="operator">></span>value);
<span class="type"><a href="../qtgui/qaccessible.html">QAccessible</a></span><span class="operator">::</span>updateAccessibility(<span class="operator">&</span>event);
...
}</pre>
<p>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.</p>
<p>The interface must be able to calculate bounding rectangles of itself and any children that do not provide an interface of their own. The <code>QAccessibleSlider</code> has three such children identified by the private enum, <code>SliderElements</code>, which has the following values: <code>PageLeft</code> (the rectangle on the left hand side of the slider handle), <code>PageRight</code> (the rectangle on the right hand side of the handle), and <code>Position</code> (the slider handle). Here is the implementation of <a href="../qtgui/qaccessibleinterface.html#rect">rect()</a>:</p>
<pre class="cpp"><span class="type"><a href="../qtcore/qrect.html">QRect</a></span> <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span><span class="operator">::</span>rect(<span class="type">int</span> child) <span class="keyword">const</span>
{
...
<span class="keyword">switch</span> (child) {
<span class="keyword">case</span> PageLeft:
<span class="keyword">if</span> (slider()<span class="operator">-</span><span class="operator">></span>orientation() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>Vertical)
rect <span class="operator">=</span> <span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>width()<span class="operator">,</span> srect<span class="operator">.</span>y());
<span class="keyword">else</span>
rect <span class="operator">=</span> <span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> srect<span class="operator">.</span>x()<span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>height());
<span class="keyword">break</span>;
<span class="keyword">case</span> Position:
rect <span class="operator">=</span> srect;
<span class="keyword">break</span>;
<span class="keyword">case</span> PageRight:
<span class="keyword">if</span> (slider()<span class="operator">-</span><span class="operator">></span>orientation() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>Vertical)
rect <span class="operator">=</span> <span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(<span class="number">0</span><span class="operator">,</span> srect<span class="operator">.</span>y() <span class="operator">+</span> srect<span class="operator">.</span>height()<span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>width()<span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>height()<span class="operator">-</span> srect<span class="operator">.</span>y() <span class="operator">-</span> srect<span class="operator">.</span>height());
<span class="keyword">else</span>
rect <span class="operator">=</span> <span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(srect<span class="operator">.</span>x() <span class="operator">+</span> srect<span class="operator">.</span>width()<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>width() <span class="operator">-</span> srect<span class="operator">.</span>x() <span class="operator">-</span> srect<span class="operator">.</span>width()<span class="operator">,</span> slider()<span class="operator">-</span><span class="operator">></span>height());
<span class="keyword">break</span>;
<span class="keyword">default</span>:
<span class="keyword">return</span> <span class="type"><a href="../qtwidgets/qaccessibleabstractslider.html">QAccessibleAbstractSlider</a></span><span class="operator">::</span>rect(child);
}
...</pre>
<p>The first part of the function, which we have omitted, uses the current <a href="../qtwidgets/qstyle.html">style</a> to calculate the slider handle's bounding rectangle; it is stored in <code>srect</code>. Notice that child 0, covered in the default case in the above code, is the slider itself, so we can simply return the <a href="../qtwidgets/qslider.html">QSlider</a> bounding rectangle obtained from the superclass, which is effectively the value obtained from <a href="../qtwidgets/qaccessiblewidget.html#rect">QAccessibleWidget::rect</a>().</p>
<pre class="cpp"> <span class="type"><a href="../qtcore/qpoint.html">QPoint</a></span> tp <span class="operator">=</span> slider()<span class="operator">-</span><span class="operator">></span>mapToGlobal(<span class="type"><a href="../qtcore/qpoint.html">QPoint</a></span>(<span class="number">0</span><span class="operator">,</span><span class="number">0</span>));
<span class="keyword">return</span> <span class="type"><a href="../qtcore/qrect.html">QRect</a></span>(tp<span class="operator">.</span>x() <span class="operator">+</span> rect<span class="operator">.</span>x()<span class="operator">,</span> tp<span class="operator">.</span>y() <span class="operator">+</span> rect<span class="operator">.</span>y()<span class="operator">,</span> rect<span class="operator">.</span>width()<span class="operator">,</span> rect<span class="operator">.</span>height());
}</pre>
<p>Before the rectangle is returned it must be mapped to screen coordinates.</p>
<p>The QAccessibleSlider must reimplement <a href="../qtgui/qaccessibleinterface.html#childCount">QAccessibleInterface::childCount</a>() since it manages children without interfaces.</p>
<p>The <a href="../qtgui/qaccessibleinterface.html#text">text()</a> function returns the <a href="../qtgui/qaccessible.html#Text-enum">QAccessible::Text</a> strings for the slider:</p>
<pre class="cpp"><span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span><span class="operator">::</span>text(Text t<span class="operator">,</span> <span class="type">int</span> child) <span class="keyword">const</span>
{
<span class="keyword">if</span> (<span class="operator">!</span>slider()<span class="operator">-</span><span class="operator">></span>isVisible())
<span class="keyword">return</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span>();
<span class="keyword">switch</span> (t) {
<span class="keyword">case</span> Value:
<span class="keyword">if</span> (<span class="operator">!</span>child <span class="operator">|</span><span class="operator">|</span> child <span class="operator">=</span><span class="operator">=</span> <span class="number">2</span>)
<span class="keyword">return</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span><span class="operator">::</span>number(slider()<span class="operator">-</span><span class="operator">></span>value());
<span class="keyword">return</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span>();
<span class="keyword">case</span> Name:
<span class="keyword">switch</span> (child) {
<span class="keyword">case</span> PageLeft:
<span class="keyword">return</span> slider()<span class="operator">-</span><span class="operator">></span>orientation() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>Horizontal <span class="operator">?</span>
<span class="type"><a href="../qtwidgets/qslider.html">QSlider</a></span><span class="operator">::</span>tr(<span class="string">"Page left"</span>) : <span class="type"><a href="../qtwidgets/qslider.html">QSlider</a></span><span class="operator">::</span>tr(<span class="string">"Page up"</span>);
<span class="keyword">case</span> Position:
<span class="keyword">return</span> <span class="type"><a href="../qtwidgets/qslider.html">QSlider</a></span><span class="operator">::</span>tr(<span class="string">"Position"</span>);
<span class="keyword">case</span> PageRight:
<span class="keyword">return</span> slider()<span class="operator">-</span><span class="operator">></span>orientation() <span class="operator">=</span><span class="operator">=</span> <span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>Horizontal <span class="operator">?</span>
<span class="type"><a href="../qtwidgets/qslider.html">QSlider</a></span><span class="operator">::</span>tr(<span class="string">"Page right"</span>) : <span class="type"><a href="../qtwidgets/qslider.html">QSlider</a></span><span class="operator">::</span>tr(<span class="string">"Page down"</span>);
}
<span class="keyword">break</span>;
<span class="keyword">default</span>:
<span class="keyword">break</span>;
}
<span class="keyword">return</span> <span class="type"><a href="../qtwidgets/qaccessibleabstractslider.html">QAccessibleAbstractSlider</a></span><span class="operator">::</span>text(t<span class="operator">,</span> child);
}</pre>
<p>The <code>slider()</code> function returns a pointer to the interface's <a href="../qtwidgets/qslider.html">QSlider</a>. Some values are left for the superclass's implementation. Not all values are appropriate for all accessible objects, as you can see for <a href="../qtgui/qaccessible.html#Text-enum">QAccessible::Value</a> case. You should just return an empty string for those values where no relevant text can be provided.</p>
<p>The implementation of the <a href="../qtgui/qaccessibleinterface.html#role">role()</a> function is straightforward:</p>
<pre class="cpp"><span class="type"><a href="../qtgui/qaccessible.html">QAccessible</a></span><span class="operator">::</span>Role <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span><span class="operator">::</span>role(<span class="type">int</span> child) <span class="keyword">const</span>
{
<span class="keyword">switch</span> (child) {
<span class="keyword">case</span> PageLeft:
<span class="keyword">case</span> PageRight:
<span class="keyword">return</span> PushButton;
<span class="keyword">case</span> Position:
<span class="keyword">return</span> Indicator;
<span class="keyword">default</span>:
<span class="keyword">return</span> Slider;
}
}</pre>
<p>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.</p>
<p>Next, the accessible interface needs to return the <a href="../qtgui/qaccessible-state.html">states</a> that the slider can be in. We look at parts of the <code>state()</code> implementation to show how just a few of the states are handled:</p>
<pre class="cpp"><span class="type"><a href="../qtgui/qaccessible.html">QAccessible</a></span><span class="operator">::</span>State <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span><span class="operator">::</span>state(<span class="type">int</span> child) <span class="keyword">const</span>
{
<span class="keyword">const</span> State parentState <span class="operator">=</span> <span class="type"><a href="../qtwidgets/qaccessibleabstractslider.html">QAccessibleAbstractSlider</a></span><span class="operator">::</span>state(<span class="number">0</span>);
...
<span class="keyword">switch</span> (child) {
<span class="keyword">case</span> PageLeft:
<span class="keyword">if</span> (slider<span class="operator">-</span><span class="operator">></span>value() <span class="operator"><</span><span class="operator">=</span> slider<span class="operator">-</span><span class="operator">></span>minimum())
state <span class="operator">|</span><span class="operator">=</span> Unavailable;
<span class="keyword">break</span>;
<span class="keyword">case</span> PageRight:
<span class="keyword">if</span> (slider<span class="operator">-</span><span class="operator">></span>value() <span class="operator">></span><span class="operator">=</span> slider<span class="operator">-</span><span class="operator">></span>maximum())
state <span class="operator">|</span><span class="operator">=</span> Unavailable;
<span class="keyword">break</span>;
<span class="keyword">case</span> Position:
<span class="keyword">default</span>:
<span class="keyword">break</span>;
}
<span class="keyword">return</span> state;
}</pre>
<p>The superclass implementation of <a href="../qtgui/qaccessibleinterface.html#state">state()</a>, uses the <a href="../qtgui/qaccessibleinterface.html#state">QAccessibleInterface::state</a>() implementation. We simply need to disable the buttons if the slider is at its minimum or maximum.</p>
<p>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.</p>
<a name="handling-action-requests-from-clients"></a>
<h3 >Handling Action Requests from Clients</h3>
<p>Applications can expose actions, which can be invoked by the client. In order to support actions in an object, inherit the <a href="../qtgui/qaccessibleactioninterface.html">QAccessibleActionInterface</a>.</p>
<p>Interactive elements should expose functionality triggered by mouse interaction, for example. A button should, for example, implement a click action.</p>
<p>Setting the focus is another action that should be implemented for widgets that accept receive the focus.</p>
<p>You need to re-implement <a href="../qtgui/qaccessibleactioninterface.html#actionNames">actionNames()</a> to return a list of all actions that the object supports. This list should not be localized.</p>
<p>There are two functions that give information about the actions that must return localized strings: <a href="../qtgui/qaccessibleactioninterface.html#localizedActionName">localizedActionName()</a> and <a href="../qtgui/qaccessibleactioninterface.html#localizedActionDescription">localizedActionDescription()</a>. 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".</p>
<p>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.</p>
<p>Of course the action also needs a way to be triggered. <a href="../qtgui/qaccessibleactioninterface.html#doAction">doAction()</a> should invoke the action as advertised by name and description.</p>
<p>To see examples on how to implement actions and methods, you could examine the implementations for Qt's standard widgets such as QAccessiblePushButton.</p>
<a name="implementing-accessible-plugins"></a>
<h3 >Implementing Accessible Plugins</h3>
<p>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.</p>
<p>Creating an accessible plugin is achieved by inheriting <a href="../qtgui/qaccessibleplugin.html">QAccessiblePlugin</a>, defining the supported class names in the plugin's JSON description and reimplementing <a href="../qtgui/qaccessibleplugin.html#create">create()</a> from <a href="../qtgui/qaccessibleplugin.html">QAccessiblePlugin</a>. The <code>.pro</code> 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.</p>
<p>We will go through the implementation of <code>SliderPlugin</code>, which is an accessible plugin that produces the QAccessibleSlider interface from the <a href="accessible-qwidget.html#qaccessiblewidget-example">QAccessibleWidget Example</a>. We start with the <code>key()</code> function:</p>
<pre class="cpp"><span class="type"><a href="../qtcore/qstringlist.html">QStringList</a></span> SliderPlugin<span class="operator">::</span>keys() <span class="keyword">const</span>
{
<span class="keyword">return</span> <span class="type"><a href="../qtcore/qstringlist.html">QStringList</a></span>() <span class="operator"><</span><span class="operator"><</span> QLatin1String(<span class="string">"QSlider"</span>);
}</pre>
<p>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 <code>create()</code> function:</p>
<pre class="cpp"><span class="type"><a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a></span> <span class="operator">*</span>SliderPlugin<span class="operator">::</span>create(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&</span>classname<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>object)
{
<span class="type"><a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a></span> <span class="operator">*</span>interface <span class="operator">=</span> <span class="number">0</span>;
<span class="keyword">if</span> (classname <span class="operator">=</span><span class="operator">=</span> QLatin1String(<span class="string">"QSlider"</span>) <span class="operator">&</span><span class="operator">&</span> object <span class="operator">&</span><span class="operator">&</span> object<span class="operator">-</span><span class="operator">></span>isWidgetType())
interface <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span>(<span class="keyword">static_cast</span><span class="operator"><</span><span class="type"><a href="../qtwidgets/qwidget.html">QWidget</a></span> <span class="operator">*</span><span class="operator">></span>(object));
<span class="keyword">return</span> interface;
}</pre>
<p>We check whether the interface requested is for <a href="../qtwidgets/qslider.html">QSlider</a>; if it is, we create and return an interface for it. Note that <code>object</code> will always be an instance of <code>classname</code>. You must return 0 if you do not support the class. <a href="../qtgui/qaccessible.html#updateAccessibility">updateAccessibility()</a> checks with the available accessibility plugins until it finds one that does not return 0.</p>
<p>Finally, you need to include macros in the cpp file:</p>
<pre class="cpp"> Q_OBJECT
Q_PLUGIN_METADATA(IID <span class="string">"org.qt-project.Qt.Examples.Accessibility.SliderPlugin"</span> FILE <span class="string">"slider.json"</span>)</pre>
<p>The <a href="../qtcore/qtplugin.html#Q_PLUGIN_METADATA">Q_PLUGIN_METADATA</a> macro exports the plugin in the <code>SliderPlugin</code> class into the <code>acc_sliderplugin</code> 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 <a href="plugins-howto.html">overview document</a>.</p>
<p>It does not matter if you need the plugin to be statically or dynamically linked with the application.</p>
<a name="implementing-interface-factories"></a>
<h3 >Implementing Interface Factories</h3>
<p>If you do not want to provide plugins for your accessibility interfaces, you can use an interface factory (<a href="../qtgui/qaccessible.html#InterfaceFactory-typedef">QAccessible::InterfaceFactory</a>), which is the recommended way to provide accessible interfaces in a statically-linked application.</p>
<p>A factory is a function pointer for a function that takes the same parameters as <a href="../qtgui/qaccessibleplugin.html">QAccessiblePlugin</a>'s <a href="../qtgui/qaccessibleplugin.html#create">create()</a> - a <a href="../qtcore/qstring.html">QString</a> and a <a href="../qtcore/qobject.html">QObject</a>. It also works the same way. You install the factory with the <a href="../qtgui/qaccessible.html#installFactory">installFactory()</a> function. We give an example of how to create a factory for the <code>QAccessibleSlider</code> interface:</p>
<pre class="cpp"><span class="type"><a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a></span> <span class="operator">*</span>sliderFactory(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&</span>classname<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>object)
{
<span class="type"><a href="../qtgui/qaccessibleinterface.html">QAccessibleInterface</a></span> <span class="operator">*</span>interface <span class="operator">=</span> <span class="number">0</span>;
<span class="keyword">if</span> (classname <span class="operator">=</span><span class="operator">=</span> QLatin1String(<span class="string">"QSlider"</span>) <span class="operator">&</span><span class="operator">&</span> object <span class="operator">&</span><span class="operator">&</span> object<span class="operator">-</span><span class="operator">></span>isWidgetType())
interface <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="../qtwidgets/qaccessibleslider.html">QAccessibleSlider</a></span>(<span class="keyword">static_cast</span><span class="operator"><</span><span class="type"><a href="../qtwidgets/qwidget.html">QWidget</a></span> <span class="operator">*</span><span class="operator">></span>(object));
<span class="keyword">return</span> interface;
}
<span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span>argv<span class="operator">[</span><span class="operator">]</span>)
{
<span class="type"><a href="../qtwidgets/qapplication.html">QApplication</a></span> app(argc<span class="operator">,</span> argv);
<span class="type"><a href="../qtgui/qaccessible.html">QAccessible</a></span><span class="operator">::</span>installFactory(sliderFactory);
...
}</pre>
</div>
<!-- @@@accessible-qwidget.html -->
<p class="naviNextPrevious footerNavi">
<a class="prevPage" href="accessible.html">Accessibility</a>
<a class="nextPage" href="accessible-qtquick.html">Accessibility for Qt Quick Applications</a>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</acronym> 2015 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.<br> The documentation provided herein is licensed under the terms of the <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> as published by the Free Software Foundation.<br> Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property
of their respective owners. </p>
</div>
</body>
</html>
|