C++ NVDA屏幕读取器请求错误的QACCESS::InterfaceType
我在Qt5.9.1上 我正在尝试通过屏幕阅读器访问应用程序。我有一个自定义小部件(我们称之为C++ NVDA屏幕读取器请求错误的QACCESS::InterfaceType,c++,qt,accessibility,screen-readers,nvda,C++,Qt,Accessibility,Screen Readers,Nvda,我在Qt5.9.1上 我正在尝试通过屏幕阅读器访问应用程序。我有一个自定义小部件(我们称之为MyWidget),其中包含大量文本。文本是使用QPainter绘制的,这就是为什么使用自定义小部件,而不是像QTextBrowser这样的东西 我为AccessibleWidget类中的小部件实现了QAccessibleTextInterface,该类派生自QAccessibleWidget和QAccessibleTextInterface。它可以在Linux下与Orca一起工作,但在Windows 7
MyWidget
),其中包含大量文本。文本是使用QPainter
绘制的,这就是为什么使用自定义小部件,而不是像QTextBrowser
这样的东西
我为AccessibleWidget
类中的小部件实现了QAccessibleTextInterface
,该类派生自QAccessibleWidget
和QAccessibleTextInterface
。它可以在Linux下与Orca一起工作,但在Windows 7中与NVDA一起使用时,QAccessibleInterface::interface_cast()
请求错误的接口类型。使用Orca,我会收到对QAccessible::TextInterface
的请求。在NVDA中,它总是QAccessible::ValueInterface
可访问性mywidget
定义为:
class AccessibleMyWidget:
public QAccessibleWidget, public QAccessibleTextInterface {
public:
explicit AccessibleMyWidget(QWidget* w)
: QAccessibleWidget(w, QAccessible::EditableText)
{
Q_ASSERT(isValid());
}
void* interface_cast(QAccessible::InterfaceType t) override
{
if (t == QAccessible::TextInterface) {
// !!! This is never requested with NVDA !!!
return static_cast<QAccessibleTextInterface*>(this);
}
return QAccessibleWidget::interface_cast(t);
}
/*
* QAccessibleTextInterface implementation below this point.
*/
void addSelection(int startOffset, int endOffset) override;
QString attributes(int offset, int* startOffset,
int* endOffset) const override;
// etc.
};
class AccessibleMyWidget:
公共QAccessibleWidget,公共QAccessibleTextInterface{
公众:
显式可访问的Widget(QWidget*w)
:QAccessibleWidget(w,QAccessible::EditableText)
{
Q_断言(isValid());
}
void*接口类型转换(QAccessible::InterfaceType t)覆盖
{
if(t==QACCESS::TextInterface){
//!!!这是NVDA从未要求的!!!
返回静态_cast(此);
}
返回QAccessibleWidget::interface_cast(t);
}
/*
*QAccessibleTextInterface实现低于此点。
*/
无效添加选择(int STARTOFSET,int endOffset)覆盖;
QString属性(int offset,int*startOffset,
int*endOffset)常量覆盖;
//等等。
};
有了Linux下的Orca,一切似乎都按预期运行。我为TextInterface
调用interface\u cast()
,然后调用QAccessibleTextInterface
的各种函数。使用Linux下的NVDA,我只得到interface\u cast()
对ValueInterface
的调用,并且没有调用QAccessibleTextInterface
函数。这意味着MyWidget
完全不可访问,除非我重写QAccessibleWidget::text()
并将所有文本作为单个字符串返回,这意味着没有光标导航,没有选择支持。。。在这一点上,它基本上变成了一个QLabel
,但是有大量的文本,因此很难使用
我在这里遗漏了什么?嗯,一位NVDA开发人员帮助我找到了这个问题。这是因为Qt的MinGW版本禁用了IAccessible2,并使用MSAA(Microsoft主动可访问性),MSAA不支持这些接口中的任何一个。IA2需要COM,而MinGW不支持 所以我必须从GCC/MinGW切换到MSVC才能在Windows上运行。太糟糕了,在可预见的未来,这实际上不是一个选项:-/ 2020年更新:
自那时起,这一问题已得到解决。不确定确切时间,但当前的mingw Qt版本现在支持此功能。是指出于公众利益的from软件,还是指与Qt一起工作并支持32位和64位Windows的fork?@SlySven它是mingw-w64。然而,2017年,Qt的mingw构建已禁用COM。但从那时起,这个问题就得到了解决。我会更新答案。那么,你的意思是:2017年Qt使用了“Mingw”,并且COM接口被禁用,但从那时起,他们已经切换到“Mingw-w64”,或者他们甚至在2017年使用了“Mingw-w64”,但他们当时禁用了COM,但现在不是吗?@SlySven我的意思是,他们使用的是Mingw-w64,但是Qt只在msvc构建中启用了COM。现在他们也为mingw启用了它。(现在人们说“mingw”其实是指“mingw-w64”。)