Qt World Summit: Submit your Presentation

position of QTapGesture on QTabWidget

  • Hi :)
    On a QTabWidget accepting QTapGesture, tapping generates 3 events: the first with gesture in state GestureStarted, the second with GestureUpdated and the third with GestureFinished. The QPointF returned by QTapGesture.position() is different between the first event and the others. It looks like the first value is relative to the whole QTabWidget, while the other two values are relative to the QStackedWidget. The difference is the size of the QTabBar. I expected the position to stay the same in all events. How can I know, without subclassing qtabbar and qtabwidget, the global tap position?
    I'm running Ubuntu 19.10 eoan, python3-pyqt5 5.12.3 from the standard repository.

    $ python3 minimal_tap_on_qtabwidget.py 
    tap state 1
    tap position PyQt5.QtCore.QPointF(108.02645874023438, 64.21989440917969)
    tabBar size PyQt5.QtCore.QSize(85, 35)
    tap state 2
    tap position PyQt5.QtCore.QPointF(106.02645874023438, 29.219894409179688)
    tabBar size PyQt5.QtCore.QSize(85, 35)
    tap state 3
    tap position PyQt5.QtCore.QPointF(106.02645874023438, 29.219894409179688)
    tabBar size PyQt5.QtCore.QSize(85, 35)

    Here with a standard tabBar to the NORTH, the difference is on the Y coordinate. With a tabBar to the WEST, the difference will be in the X coordinate.

    # minimal_tap_on_qtabwidget.py
    import sys
    from PyQt5 import Qt, QtCore
    class TabWidget(Qt.QTabWidget):
        def __init__(self, *args, **kwargs):
            super(TabWidget, self).__init__(*args, **kwargs)
            self.addTab(Qt.QWidget(), Qt.QIcon(), 'mytab')
        def event(self, event):
            if event.type() == Qt.QEvent.Gesture:
                return self.on_gesture_event(event)
            return super(TabWidget, self).event(event)
        def on_gesture_event(self, gesture_event):
            tap = gesture_event.gesture(QtCore.Qt.TapGesture)
            if tap:
                print('tap state {}'.format(tap.state()))
            return True
        def on_tap(self, tap_gesture):
            tap_pos = tap_gesture.position()
            print('tap position {}'.format(tap_pos))
            print('tabBar size {}'.format(self.tabBar().size()))
    def main():
        qapp = Qt.QApplication([])
        qapp.setAttribute(QtCore.Qt.AA_SynthesizeMouseForUnhandledTouchEvents, False)
        tab_widget = TabWidget()
    if __name__ == '__main__':

Log in to reply