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 \qmlattachedproperty 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 \qmlattachedproperty 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 \qmlattachedproperty 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 \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty 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/*! \qmlattachedproperty int QtQuick::Accessible::levelAttribute
186 \brief This property holds the level of this item within a hierarchical structure.
187 This property is used to populate QAccessible::Attribute::Level of the \l QAccessibleAttributesInterface.
188
189 It is relevant when the role is \l QAccessible::Heading and its needed to distinguish between different levels of headings.
190 \since 6.13
191 By default this property is \c 0.
192 \sa QAccessible::Attribute
193*/
194/*! \qmlattachedproperty bool QtQuick::Accessible::ignored
195 \brief This property holds whether this item should be ignored by the accessibility framework.
196
197 Sometimes an item is part of a group of items that should be treated as one. For example two labels might be
198 visually placed next to each other, but separate items. For accessibility purposes they should be treated as one
199 and thus they are represented by a third invisible item with the right geometry.
200
201 For example a speed display adds "m/s" as a smaller label:
202 \qml
203 Row {
204 Label {
205 id: speedLabel
206 text: "Speed: 5"
207 Accessible.ignored: true
208 }
209 Label {
210 text: qsTr("m/s")
211 Accessible.ignored: true
212 }
213 Accessible.role: Accessible.StaticText
214 Accessible.name: speedLabel.text + " meters per second"
215 }
216 \endqml
217
218 \since 5.4
219 By default this property is \c false.
220*/
221/*! \qmlattachedproperty bool QtQuick::Accessible::multiLine
222 \brief This property holds whether this item has multiple text lines.
223
224 By default this property is \c false.
225*/
226/*! \qmlattachedproperty bool QtQuick::Accessible::readOnly
227 \brief This property indicates that a text field is read only.
228
229 It is relevant when the role is \l QAccessible::EditableText and set to be read-only.
230 By default this property is \c false.
231*/
232/*! \qmlattachedproperty bool QtQuick::Accessible::selected
233 \brief This property holds whether this item is selected.
234
235 By default this property is \c false.
236 \sa selectable
237*/
238/*! \qmlattachedproperty bool QtQuick::Accessible::selectable
239 \brief This property holds whether this item can be selected.
240
241 By default this property is \c false.
242 \sa selected
243*/
244/*! \qmlattachedproperty bool QtQuick::Accessible::pressed
245 \brief This property holds whether this item is pressed (for example a button during a mouse click).
246
247 By default this property is \c false.
248*/
249/*! \qmlattachedproperty bool QtQuick::Accessible::checkStateMixed
250 \brief This property holds whether this item is in the partially checked state.
251
252 By default this property is \c false.
253 \sa checked, checkable
254*/
255/*! \qmlattachedproperty bool QtQuick::Accessible::defaultButton
256 \brief This property holds whether this item is the default button of a dialog.
257
258 By default this property is \c false.
259*/
260/*! \qmlattachedproperty bool QtQuick::Accessible::passwordEdit
261 \brief This property holds whether this item is a password text edit.
262
263 By default this property is \c false.
264*/
265/*! \qmlattachedproperty bool QtQuick::Accessible::selectableText
266 \brief This property holds whether this item contains selectable text.
267
268 By default this property is \c false.
269*/
270/*! \qmlattachedproperty Item QtQuick::Accessible::labelledBy
271 \brief This property holds the item that is used as a label for this item.
272
273 Setting this property automatically sets up the labelFor relation of the other object.
274
275 By default this property is \c undefined.
276
277 \since 6.10
278 */
279/*! \qmlattachedproperty Item QtQuick::Accessible::labelFor
280 \brief This property holds the item that this item is a label for.
281
282 Setting this property automatically sets up the labelledBy relation of the other object.
283
284 By default this property is \c undefined.
285
286 \since 6.10
287 */
288
289/*!
290 \qmlattachedsignal QtQuick::Accessible::pressAction()
291
292 This signal is emitted when a press action is received from an assistive tool such as a screen-reader.
293*/
294/*!
295 \qmlattachedsignal QtQuick::Accessible::toggleAction()
296
297 This signal is emitted when a toggle action is received from an assistive tool such as a screen-reader.
298*/
299/*!
300 \qmlattachedsignal QtQuick::Accessible::increaseAction()
301
302 This signal is emitted when a increase action is received from an assistive tool such as a screen-reader.
303*/
304/*!
305 \qmlattachedsignal QtQuick::Accessible::decreaseAction()
306
307 This signal is emitted when a decrease action is received from an assistive tool such as a screen-reader.
308*/
309/*!
310 \qmlattachedsignal QtQuick::Accessible::showOnScreenAction()
311
312 This signal is emitted when an assistive tool such as a screen-reader detects a partially visible element
313 and requests it to be fully visible.
314*/
315/*!
316 \qmlattachedsignal QtQuick::Accessible::scrollUpAction()
317
318 This signal is emitted when a scroll up action is received from an assistive tool such as a screen-reader.
319*/
320/*!
321 \qmlattachedsignal QtQuick::Accessible::scrollDownAction()
322
323 This signal is emitted when a scroll down action is received from an assistive tool such as a screen-reader.
324*/
325/*!
326 \qmlattachedsignal QtQuick::Accessible::scrollLeftAction()
327
328 This signal is emitted when a scroll left action is received from an assistive tool such as a screen-reader.
329*/
330/*!
331 \qmlattachedsignal QtQuick::Accessible::scrollRightAction()
332
333 This signal is emitted when a scroll right action is received from an assistive tool such as a screen-reader.
334*/
335/*!
336 \qmlattachedsignal QtQuick::Accessible::previousPageAction()
337
338 This signal is emitted when a previous page action is received from an assistive tool such as a screen-reader.
339*/
340/*!
341 \qmlattachedsignal QtQuick::Accessible::nextPageAction()
342
343 This signal is emitted when a next page action is received from an assistive tool such as a screen-reader.
344*/
345
346QMetaMethod QQuickAccessibleAttached::sigPress;
347QMetaMethod QQuickAccessibleAttached::sigToggle;
348QMetaMethod QQuickAccessibleAttached::sigIncrease;
349QMetaMethod QQuickAccessibleAttached::sigDecrease;
350QMetaMethod QQuickAccessibleAttached::sigShowOnScreen;
351QMetaMethod QQuickAccessibleAttached::sigScrollUp;
352QMetaMethod QQuickAccessibleAttached::sigScrollDown;
353QMetaMethod QQuickAccessibleAttached::sigScrollLeft;
354QMetaMethod QQuickAccessibleAttached::sigScrollRight;
355QMetaMethod QQuickAccessibleAttached::sigPreviousPage;
356QMetaMethod QQuickAccessibleAttached::sigNextPage;
357
358QQuickAccessibleAttached::QQuickAccessibleAttached(QObject *parent)
359 : QObject(parent), m_role(QAccessible::NoRole)
360{
361 Q_ASSERT(parent);
362 // Enable accessibility for items with accessible content. This also
363 // enables accessibility for the ancestors of such items.
364 auto item = qobject_cast<QQuickItem *>(parent);
365 if (item) {
366 item->d_func()->setAccessible();
367 } else {
368 const QLatin1StringView className(QQmlData::ensurePropertyCache(parent)->firstCppMetaObject()->className());
369 if (className != QLatin1StringView("QQuickAction")) {
370 qmlWarning(parent) << "Accessible attached property must be attached to an object deriving from Item or Action";
371 return;
372 }
373 }
374 QAccessibleEvent ev(parent, QAccessible::ObjectCreated);
375 QAccessible::updateAccessibility(&ev);
376
377 if (const QMetaObject *pmo = parent->metaObject()) {
378 auto connectPropertyChangeSignal = [parent, pmo, this](
379 const char *propertyName, const char *signalName, int slotIndex)
380 {
381 // basically does this:
382 // if the parent has the property \a propertyName with the associated \a signalName:
383 // connect(parent, signalName, this, slotIndex)
384
385 // Note that we explicitly want to only connect to standard property/signal naming
386 // convention: "value" & "valueChanged"
387 // (e.g. avoid a compound property with e.g. a signal notifier named "updated()")
388 int idxProperty = pmo->indexOfProperty(propertyName);
389 if (idxProperty != -1) {
390 const QMetaProperty property = pmo->property(idxProperty);
391 const QMetaMethod signal = property.notifySignal();
392 if (signal.name() == signalName)
393 QMetaObject::connect(parent, signal.methodIndex(), this, slotIndex);
394 }
395 return;
396 };
397 const QMetaObject &smo = staticMetaObject;
398
399 QAccessibleInterface *iface = ev.accessibleInterface();
400 if (iface && iface->valueInterface()) {
401 static const int valueChangedIndex = smo.indexOfSlot("valueChanged()");
402 connectPropertyChangeSignal("value", "valueChanged", valueChangedIndex);
403 }
404
405 if (iface && iface->textInterface()) {
406 static const int cursorPositionChangedIndex =
407 smo.indexOfSlot("cursorPositionChanged()");
408 connectPropertyChangeSignal("cursorPosition", "cursorPositionChanged",
409 cursorPositionChangedIndex);
410 }
411 }
412
413 if (!sigPress.isValid()) {
414 sigPress = QMetaMethod::fromSignal(&QQuickAccessibleAttached::pressAction);
415 sigToggle = QMetaMethod::fromSignal(&QQuickAccessibleAttached::toggleAction);
416 sigIncrease = QMetaMethod::fromSignal(&QQuickAccessibleAttached::increaseAction);
417 sigDecrease = QMetaMethod::fromSignal(&QQuickAccessibleAttached::decreaseAction);
418 sigShowOnScreen = QMetaMethod::fromSignal(&QQuickAccessibleAttached::showOnScreenAction);
419 sigScrollUp = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollUpAction);
420 sigScrollDown = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollDownAction);
421 sigScrollLeft = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollLeftAction);
422 sigScrollRight = QMetaMethod::fromSignal(&QQuickAccessibleAttached::scrollRightAction);
423 sigPreviousPage = QMetaMethod::fromSignal(&QQuickAccessibleAttached::previousPageAction);
424 sigNextPage= QMetaMethod::fromSignal(&QQuickAccessibleAttached::nextPageAction);
425 }
426}
427
428QQuickAccessibleAttached::~QQuickAccessibleAttached()
429{
430}
431
432void QQuickAccessibleAttached::setRole(QAccessible::Role role)
433{
434 if (role != m_role) {
435 m_role = role;
436 Q_EMIT roleChanged();
437 // There is no way to signify role changes at the moment.
438 // QAccessible::updateAccessibility(parent(), 0, QAccessible::);
439
440 switch (role) {
441 case QAccessible::CheckBox:
442 case QAccessible::RadioButton:
443 case QAccessible::Switch:
444 if (!m_stateExplicitlySet.focusable)
445 m_state.focusable = true;
446 if (!m_stateExplicitlySet.checkable)
447 m_state.checkable = true;
448 break;
449 case QAccessible::Button:
450 case QAccessible::MenuItem:
451 case QAccessible::PageTab:
452 case QAccessible::SpinBox:
453 case QAccessible::ComboBox:
454 case QAccessible::Terminal:
455 case QAccessible::ScrollBar:
456 if (!m_stateExplicitlySet.focusable)
457 m_state.focusable = true;
458 break;
459 case QAccessible::EditableText:
460 if (!m_stateExplicitlySet.editable)
461 m_state.editable = true;
462 if (!m_stateExplicitlySet.focusable)
463 m_state.focusable = true;
464 break;
465 case QAccessible::StaticText:
466 if (!m_stateExplicitlySet.readOnly)
467 m_state.readOnly = true;
468 if (!m_stateExplicitlySet.focusable)
469 m_state.focusable = true;
470 break;
471 default:
472 break;
473 }
474 }
475}
476
477bool QQuickAccessibleAttached::wasNameExplicitlySet() const
478{
479 return m_nameExplicitlySet;
480}
481
482// Allows types to attach an accessible name to an item as a convenience,
483// so long as the user hasn't done so themselves.
484void QQuickAccessibleAttached::setNameImplicitly(const QString &name)
485{
486 setName(name);
487 m_nameExplicitlySet = false;
488}
489
490void QQuickAccessibleAttached::setDescriptionImplicitly(const QString &desc)
491{
492 if (m_descriptionExplicitlySet)
493 return;
494 setDescription(desc);
495 m_descriptionExplicitlySet = false;
496}
497
498QQuickAccessibleAttached *QQuickAccessibleAttached::qmlAttachedProperties(QObject *obj)
499{
500 return new QQuickAccessibleAttached(obj);
501}
502
503bool QQuickAccessibleAttached::ignored() const
504{
505 auto item = qobject_cast<QQuickItem *>(parent());
506 return item ? !item->d_func()->isAccessible : false;
507}
508
509void QQuickAccessibleAttached::setIgnored(bool ignored)
510{
511 auto item = qobject_cast<QQuickItem *>(parent());
512 if (item && this->ignored() != ignored) {
513 item->d_func()->isAccessible = !ignored;
514 QAccessibleEvent event(item,
515 ignored ? QAccessible::ObjectDestroyed : QAccessible::ObjectCreated);
516 QAccessible::updateAccessibility(&event);
517 emit ignoredChanged();
518 }
519}
520
521bool QQuickAccessibleAttached::doAction(const QString &actionName)
522{
523 QMetaMethod *sig = nullptr;
524 if (actionName == QAccessibleActionInterface::pressAction())
525 sig = &sigPress;
526 else if (actionName == QAccessibleActionInterface::toggleAction())
527 sig = &sigToggle;
528 else if (actionName == QAccessibleActionInterface::increaseAction())
529 sig = &sigIncrease;
530 else if (actionName == QAccessibleActionInterface::decreaseAction())
531 sig = &sigDecrease;
532 else if (actionName == QAccessibleActionInterface::showOnScreenAction())
533 sig = &sigShowOnScreen;
534 else if (actionName == QAccessibleActionInterface::scrollUpAction())
535 sig = &sigScrollUp;
536 else if (actionName == QAccessibleActionInterface::scrollDownAction())
537 sig = &sigScrollDown;
538 else if (actionName == QAccessibleActionInterface::scrollLeftAction())
539 sig = &sigScrollLeft;
540 else if (actionName == QAccessibleActionInterface::scrollRightAction())
541 sig = &sigScrollRight;
542 else if (actionName == QAccessibleActionInterface::previousPageAction())
543 sig = &sigPreviousPage;
544 else if (actionName == QAccessibleActionInterface::nextPageAction())
545 sig = &sigNextPage;
546 if (sig && isSignalConnected(*sig)) {
547 bool ret = false;
548 if (m_proxying)
549 ret = sig->invoke(m_proxying);
550 if (!ret)
551 ret = sig->invoke(this);
552 return ret;
553 }
554 return false;
555}
556
557void QQuickAccessibleAttached::availableActions(QStringList *actions) const
558{
559 if (isSignalConnected(sigPress))
560 actions->append(QAccessibleActionInterface::pressAction());
561 if (isSignalConnected(sigToggle))
562 actions->append(QAccessibleActionInterface::toggleAction());
563 if (isSignalConnected(sigIncrease))
564 actions->append(QAccessibleActionInterface::increaseAction());
565 if (isSignalConnected(sigDecrease))
566 actions->append(QAccessibleActionInterface::decreaseAction());
567 if (isSignalConnected(sigShowOnScreen))
568 actions->append(QAccessibleActionInterface::showOnScreenAction());
569 if (isSignalConnected(sigScrollUp))
570 actions->append(QAccessibleActionInterface::scrollUpAction());
571 if (isSignalConnected(sigScrollDown))
572 actions->append(QAccessibleActionInterface::scrollDownAction());
573 if (isSignalConnected(sigScrollLeft))
574 actions->append(QAccessibleActionInterface::scrollLeftAction());
575 if (isSignalConnected(sigScrollRight))
576 actions->append(QAccessibleActionInterface::scrollRightAction());
577 if (isSignalConnected(sigPreviousPage))
578 actions->append(QAccessibleActionInterface::previousPageAction());
579 if (isSignalConnected(sigNextPage))
580 actions->append(QAccessibleActionInterface::nextPageAction());
581}
582
583QString QQuickAccessibleAttached::stripHtml(const QString &html)
584{
585#ifndef QT_NO_TEXTHTMLPARSER
586 QTextDocument doc;
587 doc.setHtml(html);
588 return doc.toPlainText();
589#else
590 return html;
591#endif
592}
593
594void QQuickAccessibleAttached::setProxying(QQuickAccessibleAttached *proxying)
595{
596 if (proxying == m_proxying)
597 return;
598
599 const QMetaObject &mo = staticMetaObject;
600 if (m_proxying) {
601 // We disconnect all signals from the proxy into this object
602 auto mo = m_proxying->metaObject();
603 auto propertyCache = QQmlData::ensurePropertyCache(m_proxying);
604 for (int signalIndex = propertyCache->signalOffset();
605 signalIndex < propertyCache->signalCount(); ++signalIndex) {
606 const QMetaMethod m = mo->method(propertyCache->signal(signalIndex)->coreIndex());
607 Q_ASSERT(m.methodType() == QMetaMethod::Signal);
608 if (m.methodType() != QMetaMethod::Signal)
609 continue;
610
611 disconnect(m_proxying, m, this, m);
612 }
613 }
614
615 m_proxying = proxying;
616
617 if (m_proxying) {
618 // We connect all signals from the proxy into this object
619 auto propertyCache = QQmlData::ensurePropertyCache(m_proxying);
620 auto mo = m_proxying->metaObject();
621 for (int signalIndex = propertyCache->signalOffset();
622 signalIndex < propertyCache->signalCount(); ++signalIndex) {
623 const QMetaMethod m = mo->method(propertyCache->signal(signalIndex)->coreIndex());
624 Q_ASSERT(m.methodType() == QMetaMethod::Signal);
625 connect(proxying, m, this, m);
626 }
627 }
628
629 // We check all properties
630 for (int prop = mo.propertyOffset(); prop < mo.propertyCount(); ++prop) {
631 const QMetaProperty p = mo.property(prop);
632 if (!p.hasNotifySignal()) {
633 continue;
634 }
635
636 const QMetaMethod signal = p.notifySignal();
637 if (signal.parameterCount() == 0)
638 signal.invoke(this);
639 else
640 signal.invoke(this, Q_ARG(bool, p.read(this).toBool()));
641 }
642}
643
644/*!
645 * \qmlattachedmethod void QtQuick::Accessible::announce(string message, AnnouncementPoliteness politeness)
646 *
647 * \since 6.8
648 * Issues an announcement event with a \a message with politeness \a politeness.
649 *
650 * \sa QAccessibleAnnouncementEvent
651 */
652void QQuickAccessibleAttached::announce(const QString &message, QAccessible::AnnouncementPoliteness politeness)
653{
654 QAccessibleAnnouncementEvent event(parent(), message);
655 event.setPoliteness(politeness);
656 QAccessible::updateAccessibility(&event);
657}
658
659QQuickItem *QQuickAccessibleAttached::findRelation(QAccessible::Relation relation) const
660{
661 const auto it = std::find_if(m_relations.cbegin(), m_relations.cend(),
662 [relation](const auto &rel) {
663 return rel.second == relation;
664 });
665
666 return it != m_relations.cend() ? it->first : nullptr;
667}
668
669QT_END_NAMESPACE
670
671#include "moc_qquickaccessibleattached_p.cpp"
672
673#endif