解决一个触摸屏兼容性问题

解决使用win10系统触摸屏触控正常,而在win7系统中却触摸不了的问题。

问题还原

  • 下列代码中win10触摸板能正常工作,但在win7系统中却触摸不了。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* main.cpp */
    QQuickWidget view;
    view.setSource(QUrl("qrc:Main.qml"));
    view.show();

    /* Main.qml */
    Item {
    MouseArea {
    anchors.fill: parent
    onClicked: console.log(">>>>")
    }
    }

问题分析

  通过拦截Qt的事件队列,可以看到win10系统中的触摸事件如下:

1
2
3
4
5
6
7
QQuickMouseArea -> QEvent::TouchBegin
...
QQuickMouseArea -> QEvent::TouchEnd
...
QQuickWidget -> QEvent::MouseButtonPress
QQuickWindow -> QEvent::MouseButtonPress
QQuickMouseArea -> QEvent::MouseButtonPress

  win7中的触摸事件:

1
2
3
4
5
6
QQuickMouseArea -> QEvent::TouchBegin
...
QQuickMouseArea -> QEvent::TouchEnd
...
QQuickWidget -> QEvent::MouseButtonPress
QQuickWindow -> QEvent::MouseButtonPress

  通过触摸事件信息对比win10与win7信息中它们都触发了触摸事件,由于Qt默认将触摸事件定向到鼠标事件,但win7最后却没有触发QEvent::MouseButtonPress导致显示触摸没反应的问题。

问题解决

  • 为QWidget的派生类设置Qt::WA_AcceptTouchEvents属性,如:

    1
    view->setAttribute(Qt::WA_AcceptTouchEvents);
  • 由于QTouchEvent和QMouseEvent事件独立。想要它们合成事件可以设置QCoreApplication的setAttribute的应用标记Qt::AA_SynthesizeTouchForUnhandledMouseEventsQt::AA_SynthesizeMouseForUnhandledTouchEvents用于启用禁用触摸事件到鼠标事件或鼠标事件到触摸事件的自动合成。

  • 其中,Qt::AA_SynthesizeMouseForUnhandledTouchEvents是不接受的所有触摸事件都将转换为鼠标左键事件。默认情况下启用此属性。