Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickaccessibleattached.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#if QT_CONFIG(accessibility)
8
9#include <QtQml/qqmlinfo.h>
10
11#include "private/qquickitem_p.h"
12
13QT_BEGIN_NAMESPACE
14
15/*!
16 \qmltype Accessible
17 \nativetype QQuickAccessibleAttached
18 \brief Enables accessibility of QML items.
19
20 \inqmlmodule QtQuick
21 \ingroup qtquick-visual-utility
22 \ingroup accessibility
23
24 This class is part of the \l {Accessibility for Qt Quick Applications}.
25
26 Items the user interacts with or that give information to the user
27 need to expose their information to the accessibility framework.
28 Then assistive tools can make use of that information to enable
29 users to interact with the application in various ways.
30 This enables Qt Quick applications to be used with screen-readers for example.
31
32 The most important properties are \l name, \l description and \l role.
33
34 Example implementation of a simple button:
35 \qml
36 Rectangle {
37 id: myButton
38 Text {
39 id: label
40 text: "next"
41 }
42 Accessible.role: Accessible.Button
43 Accessible.name: label.text
44 Accessible.description: "shows the next page"
45 Accessible.onPressAction: {
46 // do a button click
47 }
48 }
49 \endqml
50 The \l role is set to \c Button to indicate the type of control.
51 \l {Accessible::}{name} is the most important information and bound to the text on the button.
52 The name is a short and consise description of the control and should reflect the visual label.
53 In this case it is not clear what the button does with the name only, so \l description contains
54 an explanation.
55 There is also a signal handler \l {Accessible::pressAction}{Accessible.pressAction} which can be invoked by assistive tools to trigger
56 the button. This signal handler needs to have the same effect as tapping or clicking the button would have.
57
58 \sa Accessibility
59*/
60
61/*!
62 \qmlproperty string QtQuick::Accessible::name
63
64 This property sets an accessible name.
65 For a button for example, this should have a binding to its text.
66 In general this property should be set to a simple and concise
67 but human readable name. Do not include the type of control
68 you want to represent but just the name.
69*/
70
71/*!
72 \qmlproperty string QtQuick::Accessible::description
73
74 This property sets an accessible description.
75 Similar to the name it describes the item. The description
76 can be a little more verbose and tell what the item does,
77 for example the functionality of the button it describes.
78*/
79
80/*!
81 \qmlproperty enumeration QtQuick::Accessible::role
82
83 This flags sets the semantic type of the widget.
84 A button for example would have "Button" as type.
85 The value must be one of \l QAccessible::Role.
86
87 Some roles have special semantics.
88 In order to implement check boxes for example a "checked" property is expected.
89
90 \table
91 \header
92 \li \b {Role}
93 \li \b {Properties and signals}
94 \li \b {Explanation}
95 \row
96 \li All interactive elements
97 \li \l focusable and \l focused
98 \li All elements that the user can interact with should have focusable set to \c true and
99 set \c focus to \c true when they have the focus. This is important even for applications
100 that run on touch-only devices since screen readers often implement a virtual focus that
101 can be moved from item to item.
102 \row
103 \li Button, CheckBox, RadioButton, Switch
104 \li \l {Accessible::pressAction}{Accessible.pressAction}
105 \li A button should have a signal handler with the name \c onPressAction.
106 This signal may be emitted by an assistive tool such as a screen-reader.
107 The implementation needs to behave the same as a mouse click or tap on the button.
108 \row
109 \li CheckBox, RadioButton, Switch
110 \li \l checkable, \l checked, \l {Accessible::toggleAction}{Accessible.toggleAction}
111
112 \li The check state of the check box. Updated on Press, Check and Uncheck actions.
113 \row
114 \li Slider, SpinBox, Dial, ScrollBar
115 \li \c value, \c minimumValue, \c maximumValue, \c stepSize
116 \li These properties reflect the state and possible values for the elements.
117 \row
118 \li Slider, SpinBox, Dial, ScrollBar
119 \li \l {Accessible::increaseAction}{Accessible.increaseAction}, \l {Accessible::decreaseAction}{Accessible.decreaseAction}
120 \li Actions to increase and decrease the value of the element.
121 \endtable
122*/
123
124/*!
125 \qmlproperty string QtQuick::Accessible::id
126
127 This property sets an identifier for the object.
128 It can be used to provide stable identifiers to UI tests.
129 By default, the identifier is set to the ID of the QML object.
130 If the ID is not set the default of \l QAccessible::Identifier is used.
131*/
132
133/*! \qmlproperty bool QtQuick::Accessible::focusable
134 \brief This property holds whether this item is focusable.
135
136 By default, this property is \c false except for items where the role is one of
137 \c CheckBox, \c RadioButton, \c Switch, \c Button, \c MenuItem, \c PageTab,
138 \c EditableText, \c SpinBox, \c ComboBox, \c Terminal or \c ScrollBar.
139 \sa focused
140*/
141/*! \qmlproperty bool QtQuick::Accessible::focused
142 \brief This property holds whether this item currently has the active focus.
143
144 By default, this property is \c false, but it will return \c true for items that
145 have \l QQuickItem::hasActiveFocus() returning \c true.
146 \sa focusable
147*/
148/*! \qmlproperty bool QtQuick::Accessible::checkable
149 \brief This property holds whether this item is checkable (like a check box or some buttons).
150
151 By default this property is \c false.
152 \sa checked
153*/
154/*! \qmlproperty bool QtQuick::Accessible::checked
155 \brief This property holds whether this item is currently checked.
156
157 By default this property is \c false.
158 \sa checkable
159*/
160/*! \qmlproperty bool QtQuick::Accessible::expandable
161 \brief This property holds whether this item is expandable.
162
163 \since 6.12
164 By default this property is \c false.
165 \sa expanded
166*/
167/*! \qmlproperty bool QtQuick::Accessible::expanded
168 \brief This property holds whether this item is currently expanded.
169
170 \since 6.12
171 By default this property is \c false.
172 \sa expandable
173*/
174/*! \qmlproperty bool QtQuick::Accessible::editable
175 \brief This property holds whether this item has editable text.
176
177 By default this property is \c false.
178*/
179/*! \qmlproperty bool QtQuick::Accessible::searchEdit
180 \brief This property holds whether this item is input for a search query.
181 This property will only affect editable text.
182
183 By default this property is \c false.
184*/
185/*! \qmlproperty bool QtQuick::Accessible::ignored
186 \brief This property holds whether this item should be ignored by the accessibility framework.
187
188 Sometimes an item is part of a group of items that should be treated as one. For example two labels might be
189 visually placed next to each other, but separate items. For accessibility purposes they should be treated as one
190 and thus they are represented by a third invisible item with the right geometry.
191
192 For example a speed display adds "m/s" as a smaller label:
193 \qml
194 Row {
195 Label {
196 id: speedLabel
197 text: "Speed: 5"
198 Accessible.ignored: true
199 }
200 Label {
201 text: qsTr("m/s")
202 Accessible.ignored: true
203 }
204 Accessible.role: Accessible.StaticText
205 Accessible.name: speedLabel.text + " meters per second"
206 }
207 \endqml
208
209 \since 5.4
210 By default this property is \c false.
211*/
212/*! \qmlproperty bool QtQuick::Accessible::multiLine
213 \brief This property holds whether this item has multiple text lines.
214
215 By default this property is \c false.
216*/
217/*! \qmlproperty bool QtQuick::Accessible::readOnly
218 \brief This property indicates that a text field is read only.
219
220 It is relevant when the role is \l QAccessible::EditableText and set to be read-only.
221 By default this property is \c false.
222*/
223/*! \qmlproperty bool QtQuick::Accessible::selected
224 \brief This property holds whether this item is selected.
225
226 By default this property is \c false.
227 \sa selectable
228*/
229/*! \qmlproperty bool QtQuick::Accessible::selectable
230 \brief This property holds whether this item can be selected.
231
232 By default this property is \c false.
233 \sa selected
234*/
235/*! \qmlproperty bool QtQuick::Accessible::pressed
236 \brief This property holds whether this item is pressed (for example a button during a mouse click).
237
238 By default this property is \c false.
239*/
240/*! \qmlproperty bool QtQuick::Accessible::checkStateMixed
241 \brief This property holds whether this item is in the partially checked state.
242
243 By default this property is \c false.
244 \sa checked, checkable
245*/
246/*! \qmlproperty bool QtQuick::Accessible::defaultButton
247 \brief This property holds whether this item is the default button of a dialog.
248
249 By default this property is \c false.
250*/
251/*! \qmlproperty bool QtQuick::Accessible::passwordEdit
252 \brief This property holds whether this item is a password text edit.
253
254 By default this property is \c false.
255*/
256/*! \qmlproperty bool QtQuick::Accessible::selectableText
257 \brief This property holds whether this item contains selectable text.
258
259 By default this property is \c false.
260*/
261/*! \qmlproperty Item QtQuick::Accessible::labelledBy
262 \brief This property holds the item that is used as a label for this item.
263
264 Setting this property automatically sets up the labelFor relation of the other object.
265
266 By default this property is \c undefined.
267
268 \since 6.10
269 */
270/*! \qmlproperty Item QtQuick::Accessible::labelFor
271 \brief This property holds the item that this item is a label for.
272
273 Setting this property automatically sets up the labelledBy relation of the other object.
274
275 By default this property is \c undefined.
276
277 \since 6.10
278 */
279
280/*!
281 \qmlsignal QtQuick::Accessible::pressAction()
282
283 This signal is emitted when a press action is received from an assistive tool such as a screen-reader.
284*/
285/*!
286 \qmlsignal QtQuick::Accessible::toggleAction()
287
288 This signal is emitted when a toggle action is received from an assistive tool such as a screen-reader.
289*/
290/*!
291 \qmlsignal QtQuick::Accessible::increaseAction()
292
293 This signal is emitted when a increase action is received from an assistive tool such as a screen-reader.
294*/
295/*!
296 \qmlsignal QtQuick::Accessible::decreaseAction()
297
298 This signal is emitted when a decrease action is received from an assistive tool such as a screen-reader.
299*/
300/*!
301 \qmlsignal QtQuick::Accessible::showOnScreenAction()
302
303 This signal is emitted when an assistive tool such as a screen-reader detects a partially visible element
304 and requests it to be fully visible.
305*/
306/*!
307 \qmlsignal QtQuick::Accessible::scrollUpAction()
308
309 This signal is emitted when a scroll up action is received from an assistive tool such as a screen-reader.
310*/
311/*!
312 \qmlsignal QtQuick::Accessible::scrollDownAction()
313
314 This signal is emitted when a scroll down action is received from an assistive tool such as a screen-reader.
315*/
316/*!
317 \qmlsignal QtQuick::Accessible::scrollLeftAction()
318
319 This signal is emitted when a scroll left action is received from an assistive tool such as a screen-reader.
320*/
321/*!
322 \qmlsignal QtQuick::Accessible::scrollRightAction()
323
324 This signal is emitted when a scroll right action is received from an assistive tool such as a screen-reader.
325*/
326/*!
327 \qmlsignal QtQuick::Accessible::previousPageAction()
328
329 This signal is emitted when a previous page action is received from an assistive tool such as a screen-reader.
330*/
331/*!
332 \qmlsignal QtQuick::Accessible::nextPageAction()
333
334 This signal is emitted when a next page action is received from an assistive tool such as a screen-reader.
335*/
336
337QMetaMethod QQuickAccessibleAttached::sigPress;
338QMetaMethod QQuickAccessibleAttached::sigToggle;
339QMetaMethod QQuickAccessibleAttached::sigIncrease;
340QMetaMethod QQuickAccessibleAttached::sigDecrease;
341QMetaMethod QQuickAccessibleAttached::sigShowOnScreen;
342QMetaMethod QQuickAccessibleAttached::sigScrollUp;
343QMetaMethod QQuickAccessibleAttached::sigScrollDown;
344QMetaMethod QQuickAccessibleAttached::sigScrollLeft;
345QMetaMethod QQuickAccessibleAttached::sigScrollRight;
346QMetaMethod QQuickAccessibleAttached::sigPreviousPage;
347QMetaMethod QQuickAccessibleAttached::sigNextPage;
348
349QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)
350 : QObject(parent), m_role(QAccessible::NoRole)
351{
352 Q_ASSERT(parent);
353 // Enable accessibility for items with accessible content. This also
354 // enables accessibility for the ancestors of such items.
355 auto item = qobject_cast<QQuickItem *>(parent);
356 if (item) {
357 item->d_func()->setAccessible();
358 } else {
359 const QLatin1StringView className(QQmlData::ensurePropertyCache(parent)->firstCppMetaObject()->className());
360 if (className != QLatin1StringView("QQuickAction")) {
361 qmlWarning(parent) << "Accessible attached property must be attached to an object deriving from Item or Action";
362 return;
363 }
364 }
365 QAccessibleEvent ev(parent, QAccessible::ObjectCreated);
366 QAccessible::updateAccessibility(&ev);
367
368 if (const QMetaObject *pmo = parent->metaObject()) {
369 auto connectPropertyChangeSignal = [parent, pmo, this](
370 const char *propertyName, const char *signalName, int slotIndex)
371 {
372 // basically does this:
373 // if the parent has the property \a propertyName with the associated \a signalName:
374 // connect(parent, signalName, this, slotIndex)
375
376 // Note that we explicitly want to only connect to standard property/signal naming
377 // convention: "value" & "valueChanged"
378 // (e.g. avoid a compound property with e.g. a signal notifier named "updated()")
379 int idxProperty = pmo->indexOfProperty(propertyName);
380 if (idxProperty != -1) {
381 const QMetaProperty property = pmo->property(idxProperty);
382 const QMetaMethod signal = property.notifySignal();
383 if (signal.name() == signalName)
384 QMetaObject::connect(parent, signal.methodIndex(), this, slotIndex);
385 }
386 return;
387 };
388 const QMetaObject &smo = staticMetaObject;
389
390 QAccessibleInterface *iface = ev.accessibleInterface();
391 if (iface && iface->valueInterface()) {
392 static const int valueChangedIndex = smo.indexOfSlot("valueChanged()");
393 connectPropertyChangeSignal("value", "valueChanged", valueChangedIndex);
394 }
395
396 if (iface && iface->textInterface()) {
397 static const int cursorPositionChangedIndex =
398 smo.indexOfSlot("cursorPositionChanged()");
399 connectPropertyChangeSignal("cursorPosition", "cursorPositionChanged",
400 cursorPositionChangedIndex);
401 }
402 }
403
404 if (!sigPress.isValid()) {
405 sigPress = QMetaMethod::fromSignal(&QQuickAccessibleAttached::pressAction);
406 sigToggle = QMetaMethod::fromSignal(&QQuickAccessibleAttached::toggleAction);
407 sigIncrease = QMetaMethod::fromSignal(&QQuickAccessibleAttached::increaseAction);
408 sigDecrease = QMetaMethod::fromSignal(&QQuickAccessibleAttached::decreaseAction);
409 sigShowOnScreen = QMetaMethod::fromSignal(&QQuickAccessibleAttached::showOnScreenAction);
410 sigScrollUp = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollUpAction);
411 sigScrollDown = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollDownAction);
412 sigScrollLeft = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollLeftAction);
413 sigScrollRight = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollRightAction);
414 sigPreviousPage = QMetaMethod::fromSignal(&QQuickAccessibleAttached::previousPageAction);
415 sigNextPage= QMetaMethod::fromSignal(&QQuickAccessibleAttached::nextPageAction);
416 }
417}
418
419QQuickAccessibleAttached::~QQuickAccessibleAttached()
420{
421}
422
423void QQuickAccessibleAttached::setRole(QAccessible::Role role)
424{
425 if (role != m_role) {
426 m_role = role;
427 Q_EMIT roleChanged();
428 // There is no way to signify role changes at the moment.
429 // QAccessible::updateAccessibility(parent(), 0, QAccessible::);
430
431 switch (role) {
432 case QAccessible::CheckBox:
433 case QAccessible::RadioButton:
434 case QAccessible::Switch:
435 if (!m_stateExplicitlySet.focusable)
436 m_state.focusable = true;
437 if (!m_stateExplicitlySet.checkable)
438 m_state.checkable = true;
439 break;
440 case QAccessible::Button:
441 case QAccessible::MenuItem:
442 case QAccessible::PageTab:
443 case QAccessible::SpinBox:
444 case QAccessible::ComboBox:
445 case QAccessible::Terminal:
446 case QAccessible::ScrollBar:
447 if (!m_stateExplicitlySet.focusable)
448 m_state.focusable = true;
449 break;
450 case QAccessible::EditableText:
451 if (!m_stateExplicitlySet.editable)
452 m_state.editable = true;
453 if (!m_stateExplicitlySet.focusable)
454 m_state.focusable = true;
455 break;
456 case QAccessible::StaticText:
457 if (!m_stateExplicitlySet.readOnly)
458 m_state.readOnly = true;
459 if (!m_stateExplicitlySet.focusable)
460 m_state.focusable = true;
461 break;
462 default:
463 break;
464 }
465 }
466}
467
468bool QQuickAccessibleAttached::wasNameExplicitlySet() const
469{
470 return m_nameExplicitlySet;
471}
472
473// Allows types to attach an accessible name to an item as a convenience,
474// so long as the user hasn't done so themselves.
475void QQuickAccessibleAttached::setNameImplicitly(const QString &name)
476{
477 setName(name);
478 m_nameExplicitlySet = false;
479}
480
481void QQuickAccessibleAttached::setDescriptionImplicitly(const QString &desc)
482{
483 if (m_descriptionExplicitlySet)
484 return;
485 setDescription(desc);
486 m_descriptionExplicitlySet = false;
487}
488
489QQuickAccessibleAttached *QQuickAccessibleAttached::qmlAttachedProperties(QObject *obj)
490{
491 return new QQuickAccessibleAttached(obj);
492}
493
494bool QQuickAccessibleAttached::ignored() const
495{
496 auto item = qobject_cast<QQuickItem *>(parent());
497 return item ? !item->d_func()->isAccessible : false;
498}
499
500void QQuickAccessibleAttached::setIgnored(bool ignored)
501{
502 auto item = qobject_cast<QQuickItem *>(parent());
503 if (item && this->ignored() != ignored) {
504 item->d_func()->isAccessible = !ignored;
505 QAccessibleEvent event(item,
506 ignored ? QAccessible::ObjectDestroyed : QAccessible::ObjectCreated);
507 QAccessible::updateAccessibility(&event);
508 emit ignoredChanged();
509 }
510}
511
512bool QQuickAccessibleAttached::doAction(const QString &actionName)
513{
514 QMetaMethod *sig = nullptr;
515 if (actionName == QAccessibleActionInterface::pressAction())
516 sig = &sigPress;
517 else if (actionName == QAccessibleActionInterface::toggleAction())
518 sig = &sigToggle;
519 else if (actionName == QAccessibleActionInterface::increaseAction())
520 sig = &sigIncrease;
521 else if (actionName == QAccessibleActionInterface::decreaseAction())
522 sig = &sigDecrease;
523 else if (actionName == QAccessibleActionInterface::showOnScreenAction())
524 sig = &sigShowOnScreen;
525 else if (actionName == QAccessibleActionInterface::scrollUpAction())
526 sig = &sigScrollUp;
527 else if (actionName == QAccessibleActionInterface::scrollDownAction())
528 sig = &sigScrollDown;
529 else if (actionName == QAccessibleActionInterface::scrollLeftAction())
530 sig = &sigScrollLeft;
531 else if (actionName == QAccessibleActionInterface::scrollRightAction())
532 sig = &sigScrollRight;
533 else if (actionName == QAccessibleActionInterface::previousPageAction())
534 sig = &sigPreviousPage;
535 else if (actionName == QAccessibleActionInterface::nextPageAction())
536 sig = &sigNextPage;
537 if (sig && isSignalConnected(*sig)) {
538 bool ret = false;
539 if (m_proxying)
540 ret = sig->invoke(m_proxying);
541 if (!ret)
542 ret = sig->invoke(this);
543 return ret;
544 }
545 return false;
546}
547
548void QQuickAccessibleAttached::availableActions(QStringList *actions) const
549{
550 if (isSignalConnected(sigPress))
551 actions->append(QAccessibleActionInterface::pressAction());
552 if (isSignalConnected(sigToggle))
553 actions->append(QAccessibleActionInterface::toggleAction());
554 if (isSignalConnected(sigIncrease))
555 actions->append(QAccessibleActionInterface::increaseAction());
556 if (isSignalConnected(sigDecrease))
557 actions->append(QAccessibleActionInterface::decreaseAction());
558 if (isSignalConnected(sigShowOnScreen))
559 actions->append(QAccessibleActionInterface::showOnScreenAction());
560 if (isSignalConnected(sigScrollUp))
561 actions->append(QAccessibleActionInterface::scrollUpAction());
562 if (isSignalConnected(sigScrollDown))
563 actions->append(QAccessibleActionInterface::scrollDownAction());
564 if (isSignalConnected(sigScrollLeft))
565 actions->append(QAccessibleActionInterface::scrollLeftAction());
566 if (isSignalConnected(sigScrollRight))
567 actions->append(QAccessibleActionInterface::scrollRightAction());
568 if (isSignalConnected(sigPreviousPage))
569 actions->append(QAccessibleActionInterface::previousPageAction());
570 if (isSignalConnected(sigNextPage))
571 actions->append(QAccessibleActionInterface::nextPageAction());
572}
573
574QString QQuickAccessibleAttached::stripHtml(const QString &html)
575{
576#ifndef QT_NO_TEXTHTMLPARSER
577 QTextDocument doc;
578 doc.setHtml(html);
579 return doc.toPlainText();
580#else
581 return html;
582#endif
583}
584
585void QQuickAccessibleAttached::setProxying(QQuickAccessibleAttached *proxying)
586{
587 if (proxying == m_proxying)
588 return;
589
590 const QMetaObject &mo = staticMetaObject;
591 if (m_proxying) {
592 // We disconnect all signals from the proxy into this object
593 auto mo = m_proxying->metaObject();
594 auto propertyCache = QQmlData::ensurePropertyCache(m_proxying);
595 for (int signalIndex = propertyCache->signalOffset();
596 signalIndex < propertyCache->signalCount(); ++signalIndex) {
597 const QMetaMethod m = mo->method(propertyCache->signal(signalIndex)->coreIndex());
598 Q_ASSERT(m.methodType() == QMetaMethod::Signal);
599 if (m.methodType() != QMetaMethod::Signal)
600 continue;
601
602 disconnect(m_proxying, m, this, m);
603 }
604 }
605
606 m_proxying = proxying;
607
608 if (m_proxying) {
609 // We connect all signals from the proxy into this object
610 auto propertyCache = QQmlData::ensurePropertyCache(m_proxying);
611 auto mo = m_proxying->metaObject();
612 for (int signalIndex = propertyCache->signalOffset();
613 signalIndex < propertyCache->signalCount(); ++signalIndex) {
614 const QMetaMethod m = mo->method(propertyCache->signal(signalIndex)->coreIndex());
615 Q_ASSERT(m.methodType() == QMetaMethod::Signal);
616 connect(proxying, m, this, m);
617 }
618 }
619
620 // We check all properties
621 for (int prop = mo.propertyOffset(); prop < mo.propertyCount(); ++prop) {
622 const QMetaProperty p = mo.property(prop);
623 if (!p.hasNotifySignal()) {
624 continue;
625 }
626
627 const QMetaMethod signal = p.notifySignal();
628 if (signal.parameterCount() == 0)
629 signal.invoke(this);
630 else
631 signal.invoke(this, Q_ARG(bool, p.read(this).toBool()));
632 }
633}
634
635/*!
636 * \qmlmethod void QtQuick::Accessible::announce(string message, AnnouncementPoliteness politeness)
637 *
638 * \since 6.8
639 * Issues an announcement event with a \a message with politeness \a politeness.
640 *
641 * \sa QAccessibleAnnouncementEvent
642 */
643void QQuickAccessibleAttached::announce(const QString &message, QAccessible::AnnouncementPoliteness politeness)
644{
645 QAccessibleAnnouncementEvent event(parent(), message);
646 event.setPoliteness(politeness);
647 QAccessible::updateAccessibility(&event);
648}
649
650QQuickItem *QQuickAccessibleAttached::findRelation(QAccessible::Relation relation) const
651{
652 const auto it = std::find_if(m_relations.cbegin(), m_relations.cend(),
653 [relation](const auto &rel) {
654 return rel.second == relation;
655 });
656
657 return it != m_relations.cend() ? it->first : nullptr;
658}
659
660QT_END_NAMESPACE
661
662#include "moc_qquickaccessibleattached_p.cpp"
663
664#endif