QWidget 애플리케이션의 접근성
소개
여기서는 Qt 접근성 인터페이스( QAccessibleInterface )와 애플리케이션을 접근 가능하게 만드는 방법에 대해 중점적으로 다룹니다.
QWidget 기반 애플리케이션의 접근성
보조 기술과 의사소통할 때, 우리는 보조 기술이 이해할 수 있는 방식으로 Qt의 사용자 인터페이스를 설명해야 합니다. Qt 애플리케이션은 QAccessibleInterface 을 사용하여 개별 UI 요소에 대한 정보를 노출합니다. 현재 Qt는 슬라이더 핸들과 같은 위젯과 위젯 파트를 지원하지만, 필요한 경우 QObject 에 대한 인터페이스도 구현할 수 있습니다. QAccessible 에는 UI를 설명하는 열거형이 포함되어 있습니다. 이 문서에서는 열거형에 대해 살펴보겠습니다.
UI의 구조는 QAccessibleInterface 서브클래스의 트리로 표현됩니다. 이것은 종종 애플리케이션의 UI를 구성하는 QWidget 계층구조의 거울입니다.
서버는 이벤트를 전송하여 클라이언트에 updateAccessibility()를 통해 객체의 변경 사항을 알리고, 클라이언트는 이벤트를 수신하도록 등록합니다. 사용 가능한 이벤트는 QAccessible::Event 열거형에 의해 정의됩니다. 그런 다음 클라이언트는 QAccessible::queryAccessibleInterface()를 통해 이벤트를 생성한 개체를 쿼리할 수 있습니다.
QAccessible 의 멤버와 열거형은 액세스 가능한 객체를 설명하는 데 사용됩니다:
- Role: 객체가 사용자 인터페이스에서 수행하는 역할(예: 창, 텍스트 편집 또는 표의 셀 등)을 설명합니다.
- Relation: 객체 계층 구조에서 객체 간의 관계를 설명합니다.
- State: 객체는 여러 가지 상태에 있을 수 있습니다. 상태의 예로는 개체가 비활성화되었는지, 포커스가 있는지, 팝업 메뉴를 제공하는지 등이 있습니다.
클라이언트는 또한 버튼의 텍스트와 같은 객체의 콘텐츠를 가져올 수 있으며, 객체는 QAccessible::Text 열거형에 정의된 문자열을 제공하여 콘텐츠에 대한 정보를 제공합니다.
접근 가능한 객체 트리
앞서 언급했듯이 트리 구조는 애플리케이션의 접근 가능한 개체로 구성됩니다. 클라이언트는 트리를 탐색하여 UI의 모든 요소에 액세스할 수 있습니다. 객체 관계는 클라이언트에 UI에 대한 정보를 제공합니다. 예를 들어 슬라이더 핸들은 슬라이더가 속한 슬라이더의 자식입니다. QAccessible::Relation 에서는 클라이언트가 객체에 요청할 수 있는 다양한 관계에 대해 설명합니다.
Qt QObject 트리와 접근 가능한 객체 트리 사이에는 직접적인 매핑이 없다는 점에 유의하세요. 예를 들어, 스크롤 막대 핸들은 접근 가능한 객체이지만 Qt의 위젯이나 객체가 아닙니다.
AT 클라이언트는 트리의 루트 객체( QApplication)를 통해 접근성 객체 트리에 액세스할 수 있습니다. QAccessibleInterface::parent(), QAccessibleInterface::childCount() 및 QAccessibleInterface::child() 함수를 사용하여 트리를 탐색할 수 있습니다.
Qt는 위젯과 Qt Quick Controls 에 대한 접근성 인터페이스를 제공합니다. QObject 서브클래스에 대한 인터페이스는 QAccessible::queryInterface()를 통해 요청할 수 있습니다. 보다 전문화된 인터페이스가 정의되지 않은 경우 기본 구현이 제공됩니다. AT-Client는 동등한 QObject, 예를 들어 스크롤 막대 핸들이 없는 접근 가능한 객체에 대한 인터페이스를 획득할 수 없지만, 부모 접근 가능한 객체의 인터페이스를 통해 일반 객체로 나타납니다(예: QAccessibleInterface::relations()로 해당 관계를 쿼리할 수 있음).
이해를 돕기 위해 접근 가능한 객체 트리의 이미지를 제시합니다. 트리 아래에는 객체 관계의 예가 있는 표가 있습니다.
하향식 순서로 레이블은 QAccessibleInterface 클래스 이름, 인터페이스가 제공되는 위젯, 객체의 Role 입니다. Position, PageLeft 및 PageRight는 각각 슬라이더 핸들, 슬라이더 홈 왼쪽 및 슬라이더 홈 오른쪽에 해당합니다. 이러한 접근 가능한 객체에는 해당하는 QObject 이 없습니다.
소스 객체 | 대상 객체 | 관계 |
---|---|---|
슬라이더 | 인디케이터 | 컨트롤러 |
인디케이터 | 슬라이더 | 제어 |
슬라이더 | 애플리케이션 | 조상 |
애플리케이션 | 슬라이더 | 자식 |
푸시 버튼 | 표시기 | 형제 |
정적 접근성 함수
접근성은 QAccessible 의 정적 함수에 의해 관리되며, 곧 살펴볼 것입니다. 이 함수는 QAccessible 인터페이스를 생성하고, 객체 트리를 구축하고, MSAA 또는 기타 플랫폼별 기술과의 연결을 시작합니다. 애플리케이션을 접근 가능하게 만드는 방법만 배우는 데 관심이 있다면 이 섹션을 접근성 구현으로 건너뛰셔도 됩니다.
클라이언트와 서버 간의 통신은 setRootObject()가 호출될 때 시작됩니다. 이 작업은 QApplication 인스턴스가 인스턴스화될 때 수행되며 직접 수행할 필요가 없습니다.
QObject 가 updateAccessibility()를 호출하면 이벤트를 수신 중인 클라이언트가 변경 사항을 통보받습니다. 이 함수는 보조 기술에 이벤트를 게시하는 데 사용되며, 접근 가능한 events 은 updateAccessibility()에 의해 게시됩니다.
queryAccessibleInterface()는 QObject에 대한 접근성 인터페이스를 반환합니다. Qt의 모든 위젯은 인터페이스를 제공하며, 다른 QObject 하위 클래스의 동작을 제어하기 위해 인터페이스가 필요한 경우 QAccessibleObject 편의 클래스가 일부 기능을 대신 구현하지만 직접 인터페이스를 구현해야 합니다.
QObject에 대한 접근성 인터페이스를 생성하는 팩토리는 QAccessible::InterfaceFactory 유형의 함수입니다. 여러 팩토리를 설치할 수 있습니다. 마지막으로 설치된 팩토리가 인터페이스를 가장 먼저 요청받게 됩니다. queryAccessibleInterface()는 팩토리를 사용하여 QObject에 대한 인터페이스를 생성합니다. 일반적으로 인터페이스를 생성하는 플러그인을 구현할 수 있으므로 팩토리에 대해 걱정할 필요가 없습니다. 나중에 두 가지 접근 방식에 대한 예제를 제공하겠습니다.
접근성 구현하기
위젯이나 다른 사용자 인터페이스 요소에 접근성 지원을 제공하려면 QAccessibleInterface 을 구현하고 QAccessiblePlugin 에 배포해야 합니다. 인터페이스를 애플리케이션에 컴파일하고 QAccessible::InterfaceFactory 을 제공할 수도 있습니다. 정적으로 연결하거나 플러그인의 복잡성을 추가하고 싶지 않은 경우 팩토리를 사용할 수 있습니다. 예를 들어 타사 라이브러리를 제공하는 경우 이점이 될 수 있습니다.
모든 위젯과 기타 사용자 인터페이스 요소에는 인터페이스와 플러그인이 있어야 합니다. 애플리케이션이 접근성을 지원하도록 하려면 다음 사항을 고려해야 합니다:
- Qt는 이미 자체 위젯에 대한 접근성을 구현하고 있습니다. 따라서 가능하면 Qt Widgets를 사용하는 것이 좋습니다.
- 접근성 클라이언트가 사용할 수 있도록 하려는 각 요소에 대해 QAccessibleInterface 을 구현해야 합니다.
- 구현한 사용자 지정 사용자 인터페이스 요소에서 접근성 이벤트를 전송해야 합니다.
일반적으로 Qt의 접근성 지원이 원래 구축된 MSAA에 어느 정도 익숙해져 있는 것이 좋습니다. 또한 고려해야 할 역할, 동작, 관계 및 이벤트를 설명하는 QAccessible 의 열거형 값에 대해서도 공부해야 합니다.
Qt의 위젯이 접근성을 어떻게 구현하는지 살펴볼 수 있습니다. MSAA 표준의 주요 문제 중 하나는 인터페이스가 일관되지 않은 방식으로 구현되는 경우가 많다는 것입니다. 이로 인해 클라이언트가 사용하기 어렵고 객체 기능을 추측해야 하는 경우가 많습니다.
QAccessibleInterface 을 상속하고 순수 가상 함수를 구현하여 인터페이스를 구현할 수 있습니다. 그러나 실제로는 일반적으로 기능의 일부를 구현하는 QAccessibleObject 또는 QAccessibleWidget 을 상속하는 것이 좋습니다. 다음 섹션에서는 QAccessibleWidget 클래스를 상속하여 위젯의 접근성을 구현하는 예제를 살펴보겠습니다.
QAccessibleObject 및 QAccessibleWidget 편의 클래스
위젯에 대한 접근성 인터페이스를 구현할 때는 일반적으로 위젯용 편의 클래스인 QAccessibleWidget 을 상속합니다. QAccessibleWidget 에서 상속되는 또 다른 사용 가능한 편의 클래스는 QAccessibleObject 으로, QObject용 인터페이스의 일부를 구현합니다.
QAccessibleWidget 은 다음과 같은 기능을 제공합니다:
- 트리 탐색과 객체의 히트 테스트를 처리합니다.
- 모든 QWidget에 공통적인 이벤트, 역할 및 작업을 처리합니다.
- 모든 위젯에서 수행할 수 있는 액션과 메서드를 처리합니다.
- rect()로 경계 사각형을 계산합니다.
- 일반 위젯에 적합한 text() 문자열을 제공합니다.
- 모든 위젯에 공통인 states 을 설정합니다.
QAccessibleWidget 예제
사용자 정의 위젯을 만들고 인터페이스를 구현하는 대신 Qt의 표준 위젯 중 하나인 QSlider 에 대해 접근성을 구현하는 방법을 보여 드리겠습니다. 접근성 인터페이스인 QAccessibleSlider는 QAccessibleAbstractSlider를 상속하고, 이는 다시 QAccessibleWidget 를 상속합니다. 이 섹션을 읽기 위해 QAccessibleAbstractSlider 클래스를 살펴볼 필요는 없습니다. 살펴보고 싶으시다면, Qt의 모든 접근 가능한 인터페이스에 대한 코드는 qtbase/src/widgets/accessible에서 찾을 수 있습니다. 다음은 QAccessibleSlider의 생성자입니다:
QAccessibleSlider::QAccessibleSlider(QWidget *w) : QAccessibleAbstractSlider(w) { Q_ASSERT(slider()); addControllingSignal(QLatin1String("valueChanged(int)")); }
슬라이더는 접근 가능한 자식에 대해 Controller 로 기능하는 복잡한 컨트롤입니다. 이 관계는 인터페이스에서 알고 있어야 합니다( parent(), child() 및 relations()의 경우). 이는 QAccessibleWidget 에서 제공하는 메커니즘인 제어 신호를 사용하여 수행할 수 있습니다. 생성자에서 이 작업을 수행합니다:
표시되는 신호의 선택은 중요하지 않으며, 이러한 방식으로 선언된 모든 신호에 동일한 원칙이 적용됩니다. 신호 이름이 올바르게 지정되었는지 확인하기 위해 QLatin1String 을 사용한다는 점에 유의하세요.
접근 가능한 객체가 사용자가 알아야 하는 방식으로 변경되면 접근 가능한 인터페이스를 통해 이벤트를 전송하여 클라이언트에게 변경 사항을 알립니다. QSlider 이 updateAccessibility()을 호출하여 값이 변경되었음을 알리는 방식입니다:
void QAbstractSlider::setValue(int value) ... QAccessibleValueChangeEvent event(this, d->value); QAccessible::updateAccessibility(&event); ... }
클라이언트가 이벤트를 수신한 직후 새 값을 쿼리할 수 있으므로 슬라이더 값이 변경된 후에 호출이 이루어집니다.
인터페이스는 자신과 자체 인터페이스를 제공하지 않는 모든 자식의 경계 사각형을 계산할 수 있어야 합니다. QAccessibleSlider
에는 SliderElements
, PageLeft
(슬라이더 핸들의 왼쪽에 있는 사각형), PageRight
(핸들의 오른쪽에 있는 사각형), Position
(슬라이더 핸들) 등의 값을 갖는 비공개 열거형에 의해 식별되는 세 개의 자식이 있습니다. 다음은 rect()의 구현입니다:
QRect QAccessibleSlider::rect(int child) const { ... switch (child) { case PageLeft: if (slider()->orientation() == Qt::Vertical) rect = QRect(0, 0, slider()->width(), srect.y()); else rect = QRect(0, 0, srect.x(), slider()->height()); break; case Position: rect = srect; break; case PageRight: if (slider()->orientation() == Qt::Vertical) rect = QRect(0, srect.y() + srect.height(), slider()->width(), slider()->height()- srect.y() - srect.height()); else rect = QRect(srect.x() + srect.width(), 0, slider()->width() - srect.x() - srect.width(), slider()->height()); break; default: return QAccessibleAbstractSlider::rect(child); } ...
생략한 함수의 첫 번째 부분은 현재 style 를 사용하여 슬라이더 핸들의 경계 사각형을 계산하고 srect
에 저장합니다. 위 코드에서 기본 사례에 포함된 자식 0은 슬라이더 자체이므로 슈퍼클래스로부터 얻은 QSlider 경계 사각형을 반환하면 되는데, 이는 사실상 QAccessibleWidget::rect()에서 얻은 값입니다.
QPoint tp = slider()->mapToGlobal(QPoint(0,0)); return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height()); }
직사각형을 반환하기 전에 화면 좌표에 매핑해야 합니다.
QAccessibleSlider는 인터페이스 없이 자식을 관리하므로 QAccessibleInterface::childCount()를 다시 구현해야 합니다.
text() 함수는 슬라이더에 대한 QAccessible::Text 문자열을 반환합니다:
QString QAccessibleSlider::text(Text t, int child) const { if (!slider()->isVisible()) return QString(); switch (t) { case Value: if (!child || child == 2) return QString::number(slider()->value()); return QString(); case Name: switch (child) { case PageLeft: return slider()->orientation() == Qt::Horizontal ? QSlider::tr("Page left") : QSlider::tr("Page up"); case Position: return QSlider::tr("Position"); case PageRight: return slider()->orientation() == Qt::Horizontal ? QSlider::tr("Page right") : QSlider::tr("Page down"); } break; default: break; } return QAccessibleAbstractSlider::text(t, child); }
slider()
함수는 인터페이스의 QSlider 에 대한 포인터를 반환합니다. 일부 값은 수퍼클래스의 구현을 위해 남겨둡니다. QAccessible::Value 사례에서 볼 수 있듯이 모든 값이 모든 접근 가능한 객체에 적합한 것은 아닙니다. 관련 텍스트를 제공할 수 없는 값에 대해서는 빈 문자열을 반환해야 합니다.
role() 함수의 구현은 간단합니다:
QAccessible::Role QAccessibleSlider::role(int child) const { switch (child) { case PageLeft: case PageRight: return PushButton; case Position: return Indicator; default: return Slider; } }
역할 함수는 모든 객체에 의해 다시 구현되어야 하며, 자신과 자체적으로 접근 가능한 인터페이스를 제공하지 않는 자식의 역할을 설명해야 합니다.
다음으로 접근 가능한 인터페이스는 슬라이더가 있을 수 있는 states 을 반환해야 합니다. state()
구현의 일부를 살펴보고 몇 가지 상태가 어떻게 처리되는지 보여드리겠습니다:
QAccessible::State QAccessibleSlider::state(int child) const { const State parentState = QAccessibleAbstractSlider::state(0); ... switch (child) { case PageLeft: if (slider->value() <= slider->minimum()) state |= Unavailable; break; case PageRight: if (slider->value() >= slider->maximum()) state |= Unavailable; break; case Position: default: break; } return state; }
state()의 수퍼클래스 구현은 QAccessibleInterface::state() 구현을 사용합니다. 슬라이더가 최소 또는 최대인 경우 버튼을 비활성화하기만 하면 됩니다.
이제 슬라이더에 대한 정보를 클라이언트에 노출했습니다. 클라이언트가 슬라이더의 값을 변경하는 등 슬라이더를 변경할 수 있도록 하려면 수행 가능한 작업에 대한 정보를 제공하고 요청 시 해당 작업을 수행해야 합니다. 이에 대해서는 다음 섹션에서 설명합니다.
클라이언트의 액션 요청 처리하기
애플리케이션은 클라이언트에서 호출할 수 있는 액션을 노출할 수 있습니다. 객체에서 액션을 지원하려면 QAccessibleActionInterface.
예를 들어 인터랙티브 요소는 마우스 상호작용에 의해 트리거되는 기능을 노출해야 합니다. 예를 들어 버튼은 클릭 동작을 구현해야 합니다.
포커스 설정은 포커스 수락을 허용하는 위젯에 대해 구현해야 하는 또 다른 동작입니다.
개체가 지원하는 모든 동작의 목록을 반환하려면 actionNames()를 다시 구현해야 합니다. 이 목록은 지역화해서는 안 됩니다.
지역화된 문자열을 반환해야 하는 동작에 대한 정보를 제공하는 두 가지 함수가 있습니다: localizedActionName() 및 localizedActionDescription(). 이 함수는 클라이언트에서 사용자에게 작업을 표시하는 데 사용할 수 있습니다. 일반적으로 이름은 간결해야 하며 "press"와 같이 한 단어로만 구성되어야 합니다.
동작이 적합한 경우 사용할 수 있는 표준 동작 이름 및 현지화 목록이 있습니다. 이렇게 하면 클라이언트가 의미를 더 쉽게 이해할 수 있고 Qt는 다양한 플랫폼에서 올바르게 노출하려고 노력할 것입니다.
물론 액션을 트리거하는 방법도 필요합니다. doAction()는 이름과 설명으로 광고된 대로 액션을 호출해야 합니다.
액션과 메서드를 구현하는 방법에 대한 예제를 보려면 QAccessiblePushButton과 같은 Qt의 표준 위젯에 대한 구현을 살펴볼 수 있습니다.
접근 가능한 플러그인 구현하기
이 섹션에서는 인터페이스에 접근 가능한 플러그인을 구현하는 절차에 대해 설명합니다. 플러그인은 런타임에 로드할 수 있는 공유 라이브러리에 저장된 클래스입니다. 필요할 때만 로드되므로 인터페이스를 플러그인으로 배포하는 것이 편리합니다.
접근성 플러그인을 만들려면 QAccessiblePlugin 을 상속하고 플러그인의 JSON 설명에 지원되는 클래스 이름을 정의한 다음 QAccessiblePlugin 에서 create() 을 다시 구현하면 됩니다. 플러그인 템플릿을 사용하려면 .pro
파일을 변경해야 하며, 플러그인이 포함된 라이브러리는 Qt가 접근성 플러그인을 검색하는 경로에 배치해야 합니다.
여기서는 QAccessibleWidget 예제에서 QAccessibleSlider 인터페이스를 생성하는 접근성 플러그인인 SliderPlugin
의 구현을 살펴 보겠습니다. key()
함수부터 시작하겠습니다:
QStringList SliderPlugin::keys() const { return QStringList() << QLatin1String("QSlider"); }
플러그인이 접근 가능한 인터페이스를 생성할 수 있는 단일 인터페이스의 클래스 이름을 반환하기만 하면 됩니다. 플러그인은 여러 개의 클래스를 지원할 수 있으므로 문자열 목록에 클래스 이름을 더 추가하기만 하면 됩니다. create()
함수로 이동합니다:
QAccessibleInterface *SliderPlugin::create(const QString &classname, QObject *object) { QAccessibleInterface *interface = 0; if (classname == QLatin1String("QSlider") && object && object->isWidgetType()) interface = new QAccessibleSlider(static_cast<QWidget *>(object)); return interface; }
요청된 인터페이스가 QSlider 용 인터페이스인지 확인하고, 그렇다면 해당 인터페이스를 생성하여 반환합니다. object
은 항상 classname
의 인스턴스입니다. 해당 클래스를 지원하지 않는 경우 0을 반환해야 합니다. updateAccessibility()는 0을 반환하지 않는 플러그인을 찾을 때까지 사용 가능한 접근성 플러그인을 확인합니다.
마지막으로 cpp 파일에 매크로를 포함해야 합니다:
Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Examples.Accessibility.SliderPlugin" FILE "slider.json")
Q_PLUGIN_METADATA 매크로는 SliderPlugin
클래스의 플러그인을 acc_sliderplugin
라이브러리로 내보냅니다. 첫 번째 인수는 플러그인 IID이고 두 번째 인수는 플러그인에 대한 메타데이터 정보를 담고 있는 선택적 json 파일입니다. 플러그인에 대한 자세한 내용은 플러그인 개요 문서를 참조하세요.
플러그인을 애플리케이션과 정적으로 연결할지 동적으로 연결할지는 중요하지 않습니다.
인터페이스 팩토리 구현하기
접근성 인터페이스용 플러그인을 제공하지 않으려면 정적으로 링크된 애플리케이션에서 접근성 인터페이스를 제공하는 데 권장되는 방법인 인터페이스 팩토리(QAccessible::InterfaceFactory)를 사용할 수 있습니다.
팩토리는 QAccessiblePlugin 의 create(), QString 및 QObject 과 동일한 매개 변수를 사용하는 함수에 대한 함수 포인터입니다. 또한 동일한 방식으로 작동합니다. installFactory () 함수를 사용하여 팩토리를 설치합니다. QAccessibleSlider
인터페이스용 팩토리를 만드는 방법에 대한 예시를 제공합니다:
QAccessibleInterface *sliderFactory(const QString &classname, QObject *object) { QAccessibleInterface *interface = 0; if (classname == QLatin1String("QSlider") && object && object->isWidgetType()) interface = new QAccessibleSlider(static_cast<QWidget *>(object)); return interface; } int main(int argc, char *argv[]) { QApplication app(argc, argv); QAccessible::installFactory(sliderFactory); ... }
관련 클래스
QML 항목의 접근성 활성화 | |
접근성과 관련된 열거형 및 정적 함수 | |
인터페이스에서 호출 불가능한 작업에 대한 지원 구현 | |
보조 기술에 의해 주어진 메시지의 발표를 요청하는 데 사용됩니다. | |
접근 가능한 객체에 대한 보고 속성 지원을 구현합니다. | |
편집 가능한 텍스트가 있는 객체에 대한 지원을 구현합니다. | |
접근성 알림을 위한 기본 클래스 | |
접근 가능한 객체에 대한 정보를 노출하는 인터페이스를 정의합니다. | |
QObject용 QAccessibleInterface의 일부를 구현합니다. | |
사용자 인터페이스 요소에 대한 접근성 정보를 제공하는 플러그인을 위한 추상 베이스 클래스 | |
선택 처리에 대한 지원을 구현합니다. | |
객체의 상태가 변경되었음을 접근성 프레임워크에 알립니다. | |
IAccessibleTable2 셀 인터페이스에 대한 지원을 구현합니다. | |
IAccessibleTable2 인터페이스에 대한 지원을 구현합니다. | |
셀이 추가되거나 제거된 표, 목록 또는 트리의 변경 사항을 나타냅니다. 변경 사항이 여러 행에 영향을 미치는 경우 firstColumn과 lastColumn은 -1을 반환합니다. 열의 경우에도 마찬가지로 행 함수는 -1을 반환할 수 있습니다. | |
커서 이동 알림 | |
텍스트 삽입 알림 | |
텍스트 처리 지원 구현 | |
텍스트 삭제 알림 | |
객체의 텍스트 선택이 변경되었음을 알립니다. | |
텍스트 변경에 대해 알립니다. 줄 편집과 같이 편집 가능한 텍스트를 지원하는 접근성을 위한 이벤트입니다. 이 이벤트는 예를 들어 선택한 텍스트의 일부가 새 텍스트를 붙여넣거나 편집기의 재정의 모드에서 대체될 때 발생합니다. | |
접근 가능한 객체의 값 변경을 설명합니다. | |
값을 조작하는 객체에 대한 지원을 구현합니다. | |
Q위젯에 대한 QAccessibleInterface를 구현합니다. |
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. 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.