Please nominate your Qt Champions for 2021!

[SOLVED] QML using QGLWidget as viewport not getting TouchEvents

  • My question is how can I send TouchEvents to widgets from a mouse driver plugin when a QGLWidget is the viewport and QML is being used. Using QT 4.7.4.

    I am using qmlviewer to run the "tic-tac-toe example": modified to support gestures (modified code is below). The program works fine when run using a frame buffer. However, when I try and use QGLWidget as the viewport the touch events are consumed in qt_translateRawTouchEvent. As best I can tell because no topLevel window is found.

    The approach to sending touch events is described in "multitouch driver for QT embedded": which calls qt_translateRawTouchEvent. Is there a better mechanism for sending touch events than qt_translateRawTouchEvent?

    Executing qmlviewer like this fails (note I don't use experimentalgestures because the QML import, see below):
    export QWS_MOUSE_PROTO=LinuxXyz:/dev/input/event0
    /etc/init.d/rc.pvr start
    qmlviewer -qws -opengl -display powervr tic-tac-toe.qml

    Executing qmlviewer like this passes:
    export QWS_MOUSE_PROTO=LinuxXyz:/dev/input/event0
    /etc/init.d/rc.pvr start
    qmlviewer -qws tic-tac-toe.qml

    To debug this, code to walk the list of all widgets was added before calling qt_translateRawTouchEvent and that code indicates that all widgets except QGLWidget are hidden (not visible) and have position 0,0. If this is correct behavior then I believe it explains why qt_translateRawTouchEvent can't find a widget to send the events to by calling topLevelAt function.

    There likely is another function to translate and send the touch event, would greatly appreciate a code snip or pointer in the right direction.

    Thank you,

    Modified tic-tac-toe to support tap gesture instead of click.
    import QtQuick 1.0
    import Qt.labs.gestures 1.0
    import "content"
    import "content/tic-tac-toe.js" as Logic

    Rectangle {
    id: game

    property bool running: true
    property real difficulty: 1.0   //chance it will actually think
    width: display.width; height: display.height + 10
    Image {
        id: boardImage
        source: "content/pics/board.png"
    Column {
        id: display
        Grid {
            id: board
            width: boardImage.width; height: boardImage.height
            columns: 3
            Repeater {
                model: 9
                TicTac {
                    width: board.width/3
                    height: board.height/3
                    GestureArea {
                    anchors.fill: parent
                    focus: true
                    onTap: {

    console.log("tap index=",index)
    if (game.running && Logic.canPlayAtPos(index)) {
    if (!Logic.makeMove(index, "X"))

        Row {
            spacing: 4
            anchors.horizontalCenter: parent.horizontalCenter
            Button {
                text: "Hard"
                pressed: game.difficulty == 1.0
                onClicked: { game.difficulty = 1.0 }
            Button {
                text: "Moderate"
                pressed: game.difficulty == 0.8
                onClicked: { game.difficulty = 0.8 }
            Button {
                text: "Easy"
                pressed: game.difficulty == 0.2
                onClicked: { game.difficulty = 0.2 }
    Text {
        id: messageDisplay
        anchors.centerIn: parent
        color: "blue"
        style: Text.Outline; styleColor: "white"
        font.pixelSize: 50; font.bold: true
        visible: false
        Timer {
            running: messageDisplay.visible
            onTriggered: {
                messageDisplay.visible = false;


  • A little progress, by sending the TouchEvents to viewport QGLWidget the gesture recognizer is recognizing the tap gesture. However, the tap gesture fails with this message:
    QGestureManager::deliverEvent: could not find the target for gesture 1

    Like the touch events, gesture manager invokes topLevelAt which returns a window ID (1001) which can't be found in the list of QWidgets (mapper).

    topLevelAt is finding the points, but the window ID used by windowAt isn't being found.

  • Modifying code in qgesturemanager.cpp function deliverEvents allows the gesture event to be delivered.

    The new code is invoked if existing methods produce a NULL target widget. The search only operates on gestures that have a hot spot. The search looks at all widgets for the best target widget that contains the hot spot.

    After that modification a target widget is found in deliverEvents and the gesture events that previously were not being delivered are processed.

    Not ideal to search all widgets, but its better than leaving the target widget null and eating a perfectly good gesture event.

Log in to reply