Results 1 to 1 of 1

Thread: Qt 6: Simulating Multi-Touch (Pan & Zoom) - Migration from Qt 5

  1. #1
    Join Date
    Feb 2025
    Posts
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Qt 6: Simulating Multi-Touch (Pan & Zoom) - Migration from Qt 5

    I am developing a Qt 6.8 touch-based application where an Android client sends touch data to a Windows server application. The Windows server receives multi-touch data and needs to simulate touch events for pan and zoom gestures.
    Issue:
    Previously, in Qt 5, the following code worked perfectly using QTouchEvent with direct setters to simulate multi-touch gestures:
    Qt 5 Working Code:

    Qt Code:
    1. struct TouchPoint {
    2. int id;
    3. short posX, posY;
    4. short lastPosX, lastPosY;
    5. short startPosX, startPosY;
    6. int state;
    7. unsigned short pressure; // 0 to 65535.
    8. };
    9.  
    10. void simulateTouch (const TouchPacket *packet)
    11. {
    12. const TouchPacket::e_touchType type = packet->touchType();
    13. const Qt::TouchPointStates states = static_cast<Qt::TouchPointStates>(packet->touchStates());
    14. const Qt::KeyboardModifiers modifiers = packet->getQtModifiers();
    15.  
    16. const int numPoints = static_cast<int> ( packet->touchPoints().size() );
    17. QList< QTouchEvent::TouchPoint > points;
    18. points.reserve( numPoints );
    19.  
    20. const int width = this->mainWindow->width();
    21. const int height = this->mainWindow->height();
    22. QWidget *parent = this->mainWindow;
    23. while (parent->parentWidget() != 0) {
    24. parent = parent->parentWidget();
    25. }
    26. // need the position of the top level widget (position is relative to desktop and not parent widget)
    27. const QPoint pos = parent->pos();
    28.  
    29. for (int i(0); i<numPoints; ++i) {
    30. const TouchPacket::TouchPoint & pkPoint( packet->touchPoints()[i] );
    31.  
    32. nextPt.setRect (QRectF());
    33. nextPt.setScreenRect (QRectF());
    34.  
    35. nextPt.setNormalizedPos(QPointF(pkPoint.posX / qreal(width), pkPoint.posY / qreal(height)));
    36. nextPt.setLastNormalizedPos(QPointF(pkPoint.lastPosX / qreal(width), pkPoint.lastPosY / qreal(height)));
    37. nextPt.setStartNormalizedPos(QPointF(pkPoint.startPosX / qreal(width), pkPoint.startPosY / qreal(height)));
    38.  
    39. nextPt.setPos( QPointF(pkPoint.posX, pkPoint.posY) );
    40. nextPt.setScenePos (nextPt.pos());
    41. nextPt.setScreenPos(pos + nextPt.pos());
    42.  
    43. nextPt.setLastPos( QPointF(pkPoint.lastPosX, pkPoint.lastPosY));
    44. nextPt.setLastScenePos (nextPt.lastPos());
    45. nextPt.setLastScreenPos(pos + nextPt.lastPos());
    46.  
    47. nextPt.setStartPos(QPointF(pkPoint.startPosX, pkPoint.startPosY));
    48. nextPt.setStartScenePos(nextPt.startPos());
    49. nextPt.setStartScreenPos(pos + nextPt.startPos());
    50.  
    51. nextPt.setPressure( 1.0 ); //((double)pkPoint.pressure ) / 65535. ) ;
    52.  
    53. nextPt.setState (static_cast<Qt::TouchPointStates>(pkPoint.state));
    54.  
    55. points.push_back(nextPt);
    56.  
    57. //qDebug() << nextPt.pos() << nextPt.normalizedPos() << nextPt.state() << nextPt.pressure() << nextPt.screenRect();
    58. }
    59.  
    60. QTouchEvent * tevent = NULL;
    61.  
    62. switch (type) {
    63. case TouchPacket::TouchBegin:
    64. tevent = new QTouchEvent( QEvent::TouchBegin, &this->touchDevice, modifiers, states, points );
    65. break;
    66. case TouchPacket::TouchCancel:
    67. tevent = new QTouchEvent( QEvent::TouchCancel, &this->touchDevice, modifiers, states, points );
    68. break;
    69. case TouchPacket::TouchEnd:
    70. tevent = new QTouchEvent( QEvent::TouchEnd, &this->touchDevice, modifiers, states, points );
    71. break;
    72. case TouchPacket::TouchUpdate:
    73. tevent = new QTouchEvent( QEvent::TouchUpdate, &this->touchDevice, modifiers, states, points );
    74. break;
    75. default:
    76. qWarning() << "Unknown touch packet" << type;
    77. }
    78.  
    79. if (tevent) {
    80. // The post event queue will take ownership of the event and delete it once it has been posted
    81. QWidget *currentWidget = this->mainWindow->childAt (points.at(0).pos().toPoint());
    82. //qDebug() << "posting to" << currentWidget << "with" << tevent->touchPoints().count() << "points" << states;
    83. QApplication::postEvent (currentWidget, tevent);
    84. }
    85. }
    To copy to clipboard, switch view to plain text mode 

    Problem in Qt 6:
    After migrating to Qt 6, QTouchEvent::TouchPoint and its setters are no longer available. Instead, Qt 6 uses QEventPoint and QMutableEventPoint, but only a few setters are available in QMutableEventPoint.
    I receive touch data in the following struct from the client:

    Qt Code:
    1. struct TouchPoint {
    2. int id;
    3. short posX, posY;
    4. short lastPosX, lastPosY;
    5. short startPosX, startPosY;
    6. int state;
    7. unsigned short pressure; // 0 to 65535
    8. };
    To copy to clipboard, switch view to plain text mode 

    I attempted to migrate the Qt 5 code using QEventPoint but ran into issues:
    Attempted Qt 6 Migration Code:

    Qt Code:
    1. void simulateTouch (const TouchPacket *packet)
    2. {
    3. const TouchPacket::e_touchType type = packet->touchType();
    4. const Qt::TouchPointStates states = static_cast<Qt::TouchPointStates>(packet->touchStates());
    5. const Qt::KeyboardModifiers modifiers = packet->getQtModifiers();
    6.  
    7. const int numPoints = static_cast<int> ( packet->touchPoints().size() );
    8. QList< QTouchEvent::TouchPoint > points;
    9. points.reserve( numPoints );
    10.  
    11. const int width = this->mainWindow->width();
    12. const int height = this->mainWindow->height();
    13. QWidget *parent = this->mainWindow;
    14. while (parent->parentWidget() != 0) {
    15. parent = parent->parentWidget();
    16. }
    17. // need the position of the top level widget (position is relative to desktop and not parent widget)
    18. const QPoint pos = parent->pos();
    19.  
    20. for (int i(0); i<numPoints; ++i) {
    21. const TouchPacket::TouchPoint & pkPoint( packet->touchPoints()[i] );
    22. QTouchEvent::TouchPoint nextPt( pkPoint.id );
    23.  
    24.  
    25.  
    26. // Assign state based on touch type
    27. QEventPoint::State pointState = QEventPoint::State::Unknown;
    28. switch (type) {
    29. case TouchPacket::TouchBegin:
    30. pointState = QEventPoint::State::Pressed;
    31. break;
    32. case TouchPacket::TouchUpdate:
    33. pointState = QEventPoint::State::Updated;
    34. break;
    35. case TouchPacket::TouchEnd:
    36. pointState = QEventPoint::State::Released;
    37. break;
    38. case TouchPacket::TouchCancel:
    39. pointState = QEventPoint::State::Stationary;
    40. break;
    41. default:
    42. break;
    43. }
    44.  
    45. QEventPoint nextPtNew(pkPoint.id, pointState, QPointF(pkPoint.posX, pkPoint.posY),
    46. QPointF(pkPoint.posX + pos.x(), pkPoint.posY + pos.y()));
    47.  
    48.  
    49. QMutableEventPoint::setPressure(nextPtNew, pkPoint.pressure);
    50. QMutableEventPoint::setState(nextPtNew, pointState);
    51. QMutableEventPoint::setGlobalLastPosition(nextPtNew, QPointF(pkPoint.posX + pos.x(), pkPoint.posY + pos.y()));
    52. QMutableEventPoint::setScenePosition(nextPtNew, QPointF(pkPoint.posX + pos.x(), pkPoint.posY + pos.y()));
    53.  
    54. points.push_back(nextPtNew);
    55. }
    56.  
    57. QTouchEvent * tevent = NULL;
    58.  
    59. switch (type) {
    60. case TouchPacket::TouchBegin:
    61. //tevent = new QTouchEvent( QEvent::TouchBegin, &this->touchDevice, modifiers, states, points );
    62. tevent = new QTouchEvent(QEvent::TouchBegin, &this->touchDevice, modifiers, points);
    63. break;
    64. case TouchPacket::TouchCancel:
    65. //tevent = new QTouchEvent( QEvent::TouchCancel, &this->touchDevice, modifiers, states, points );
    66. tevent = new QTouchEvent(QEvent::TouchCancel, &this->touchDevice, modifiers, points);
    67. break;
    68. case TouchPacket::TouchEnd:
    69. //tevent = new QTouchEvent( QEvent::TouchEnd, &this->touchDevice, modifiers, states, points );
    70. tevent = new QTouchEvent(QEvent::TouchEnd, &this->touchDevice, modifiers, points);
    71. break;
    72. case TouchPacket::TouchUpdate:
    73. //tevent = new QTouchEvent( QEvent::TouchUpdate, &this->touchDevice, modifiers, states, points );
    74. tevent = new QTouchEvent(QEvent::TouchUpdate, &this->touchDevice, modifiers, points);
    75. break;
    76. default:
    77. qWarning() << "Unknown touch packet" << type;
    78. }
    79.  
    80. if (tevent && !points.isEmpty()) {
    81. // The post event queue will take ownership of the event and delete it once it has been posted
    82. QWidget *currentWidget = this->mainWindow->childAt (points.at(0).pos().toPoint());
    83. //qDebug() << "posting to" << currentWidget << "with" << tevent->touchPoints().count() << "points" << states;
    84. QApplication::postEvent (currentWidget, tevent);
    85. }
    86. }
    To copy to clipboard, switch view to plain text mode 


    Questions:
    • How can I correctly migrate my Qt 5 touch event simulation code to Qt 6?
    • What is the correct way to construct and append QMutableEventPoint to QPointerEvent?
    • Are there additional event properties I need to set to ensure continuous pan and zoom gestures?
    • Is there a recommended approach to simulate multi-touch gestures like pan and zoom in Qt 6?
      Need alternative setters / ways for the below API
      Qt Code:
      1. QTouchEvent::TouchPoint nextPt( pkPoint.id );
      2. nextPt.setRect (QRectF());
      3. nextPt.setScreenRect (QRectF());
      4. nextPt.setNormalizedPos(QPointF(pkPoint.posX / qreal(width), pkPoint.posY / qreal(height)));
      5. nextPt.setLastNormalizedPos(QPointF(pkPoint.lastPosX / qreal(width), pkPoint.lastPosY / qreal(height)));
      6. nextPt.setStartNormalizedPos(QPointF(pkPoint.startPosX / qreal(width), pkPoint.startPosY / qreal(height)));
      7. nextPt.setPos( QPointF(pkPoint.posX, pkPoint.posY) );
      8. nextPt.setScenePos (nextPt.pos());
      9. nextPt.setScreenPos(pos + nextPt.pos());
      10. nextPt.setLastPos( QPointF(pkPoint.lastPosX, pkPoint.lastPosY));
      11. nextPt.setLastScenePos (nextPt.lastPos());
      12. nextPt.setLastScreenPos(pos + nextPt.lastPos());
      13. nextPt.setStartPos(QPointF(pkPoint.startPosX, pkPoint.startPosY));
      14. nextPt.setStartScenePos(nextPt.startPos());
      15. nextPt.setStartScreenPos(pos + nextPt.startPos());
      To copy to clipboard, switch view to plain text mode 
    • Any guidance on this migration process would be highly appreciated!
    Last edited by Kaviara; 19th February 2025 at 13:27. Reason: spelling corrections

Similar Threads

  1. WebEngineView: Avoid zoom in touch devices
    By ddonate in forum Qt Programming
    Replies: 1
    Last Post: 22nd December 2016, 11:20
  2. Multi-touch sensing in Qt
    By SSqt5.2 in forum Qt for Embedded and Mobile
    Replies: 3
    Last Post: 10th October 2014, 13:54
  3. touch and multi touch feature
    By Vishal@05 in forum Qt for Embedded and Mobile
    Replies: 6
    Last Post: 26th March 2014, 10:06
  4. Multi-touch gestures with QWS
    By HaBa in forum Qt for Embedded and Mobile
    Replies: 1
    Last Post: 11th April 2012, 16:53
  5. Simulating a touch event without a connected mobile phone
    By Rakula in forum Qt for Embedded and Mobile
    Replies: 2
    Last Post: 5th October 2010, 07:59

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.