名称: qt-widget-accessibility-audit 描述: 使用QAccessible接口和平台无障碍API对Qt Widget应用程序进行无障碍合规性审计 允许工具: Read, Grep, Glob, Bash 标签: [qt, 无障碍, wcag, a11y, 审计]
qt-widget-accessibility-audit
审计Qt Widget和Qt Quick应用程序的无障碍合规性。此技能检查QAccessible接口实现、键盘导航、屏幕阅读器兼容性以及WCAG指南的遵守情况。
功能
- 审计QAccessible接口实现
- 检查键盘导航和焦点处理
- 验证屏幕阅读器兼容性
- 验证高对比度和颜色无障碍性
- 检查文本缩放支持
- 审查无障碍名称和描述
- 使用平台无障碍工具进行测试
- 生成无障碍合规性报告
输入模式
{
"type": "object",
"properties": {
"projectPath": {
"type": "string",
"description": "Qt项目路径"
},
"auditLevel": {
"enum": ["basic", "wcag-a", "wcag-aa", "wcag-aaa"],
"default": "wcag-aa"
},
"targetPlatform": {
"enum": ["windows", "macos", "linux"],
"description": "重点进行无障碍检查的平台"
},
"checkCategories": {
"type": "array",
"items": {
"enum": ["keyboard", "screen-reader", "visual", "focus", "labels", "navigation"]
},
"default": ["keyboard", "screen-reader", "visual", "focus", "labels"]
},
"includeQml": {
"type": "boolean",
"default": true
}
},
"required": ["projectPath"]
}
输出模式
{
"type": "object",
"properties": {
"success": { "type": "boolean" },
"complianceLevel": {
"enum": ["none", "wcag-a", "wcag-aa", "wcag-aaa"]
},
"score": {
"type": "number",
"description": "无障碍评分0-100"
},
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"severity": { "enum": ["critical", "major", "minor"] },
"category": { "type": "string" },
"wcagCriteria": { "type": "string" },
"description": { "type": "string" },
"file": { "type": "string" },
"widget": { "type": "string" },
"recommendation": { "type": "string" }
}
}
},
"recommendations": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["success", "issues"]
}
无障碍检查
QAccessible接口
// 检查: 控件具有无障碍名称
bool hasAccessibleName(QWidget* widget) {
return !widget->accessibleName().isEmpty() ||
!widget->accessibleDescription().isEmpty();
}
// 检查: 自定义控件实现QAccessibleInterface
class CustomWidget : public QWidget {
// 必须为屏幕阅读器实现
QAccessibleInterface* accessibleInterface() {
return QAccessible::queryAccessibleInterface(this);
}
};
键盘导航
// 检查: 所有交互式控件都可聚焦
void auditFocusPolicy(QWidget* widget) {
if (isInteractive(widget)) {
if (widget->focusPolicy() == Qt::NoFocus) {
reportIssue("交互式控件不可聚焦", widget);
}
}
}
// 检查: Tab顺序合理
void auditTabOrder(QWidget* container) {
QList<QWidget*> tabOrder = getTabOrder(container);
// 验证从左到右、从上到下的顺序
}
视觉无障碍
// 检查: 足够的颜色对比度
bool hasAdequateContrast(QColor foreground, QColor background) {
double ratio = calculateContrastRatio(foreground, background);
return ratio >= 4.5; // WCAG AA 正常文本标准
}
// 检查: 文本可缩放
void auditFontScaling(QWidget* widget) {
QFont font = widget->font();
if (font.pixelSize() > 0) {
reportIssue("使用点大小而非像素大小", widget);
}
}
常见问题
缺少无障碍名称
// 错误: 无无障碍名称
QPushButton* btn = new QPushButton(QIcon(":/save.png"), "");
// 正确: 具有无障碍名称
QPushButton* btn = new QPushButton(QIcon(":/save.png"), "");
btn->setAccessibleName(tr("保存"));
btn->setAccessibleDescription(tr("保存当前文档"));
不可聚焦的控件
// 错误: 自定义控件不可聚焦
CustomControl* ctrl = new CustomControl();
ctrl->setFocusPolicy(Qt::NoFocus);
// 正确: 可聚焦并支持键盘
CustomControl* ctrl = new CustomControl();
ctrl->setFocusPolicy(Qt::StrongFocus);
对比度不足
// 错误: 低对比度文本
label->setStyleSheet("color: #888888; background: white;");
// 正确: WCAG AA 合规对比度
label->setStyleSheet("color: #595959; background: white;");
QML无障碍
// 无障碍QML组件
Button {
text: qsTr("提交")
Accessible.name: qsTr("提交表单")
Accessible.description: qsTr("提交注册表单")
Accessible.role: Accessible.Button
// 键盘处理
Keys.onReturnPressed: clicked()
Keys.onEnterPressed: clicked()
}
// 无障碍图像
Image {
source: "chart.png"
Accessible.name: qsTr("2024年第四季度销售图表")
Accessible.role: Accessible.Graphic
}
// 焦点指示器
Rectangle {
border.color: parent.activeFocus ? "blue" : "transparent"
border.width: 2
}
平台工具集成
Windows (UI自动化)
// 使用Windows讲述人验证
// 使用Accessibility Insights工具
void testWithUIAutomation() {
// 检查UI自动化树
// 验证所有控件具有自动化ID
}
macOS (VoiceOver)
// 使用VoiceOver验证
// 检查NSAccessibility合规性
void testWithVoiceOver() {
// 检查无障碍层次结构
// 验证标签正确播报
}
Linux (Orca/AT-SPI)
// 使用Orca屏幕阅读器验证
// 使用Accerciser进行AT-SPI检查
void testWithATSPI() {
// 检查AT-SPI树
// 验证无障碍事件
}
WCAG指南映射
| WCAG标准 | Qt实现 |
|---|---|
| 1.1.1 非文本内容 | 为图像/图标设置setAccessibleName() |
| 1.4.3 对比度 | 使用足够对比度的QPalette |
| 2.1.1 键盘 | setFocusPolicy(), 键盘处理器 |
| 2.4.3 焦点顺序 | setTabOrder() |
| 2.4.7 焦点可见 | 样式表中的焦点指示器 |
| 4.1.2 名称、角色、值 | QAccessible接口 |
最佳实践
- 设置无障碍名称: 所有交互式控件都需要名称
- 使用语义角色: 正确的QAccessible::Role
- 支持键盘: 所有功能可通过键盘访问
- 可见焦点: 清晰的焦点指示器
- 颜色独立性: 不单独依赖颜色
- 可缩放文本: 使用点大小,支持缩放
相关技能
accessibility-test-runner- 自动化测试qt-qml-component-generator- 无障碍组件desktop-accessibility流程 - 完整工作流
相关代理
accessibility-compliance-auditor- 合规性专业知识qt-cpp-specialist- Qt实现指导