Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGraphicsView and Qt::WA_AcceptTouchEvents

QGraphicsView and Qt::WA_AcceptTouchEvents

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 4 Posters 1.7k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Michael Lehn

    Is anyone able to reproduce the effect? I would like to rule out installation/platform issues.

    @Pl45m4 I made the following change:

            MainWindow(QWidget *parent = nullptr)
                : QMainWindow{parent}
                , view{new MyView}
            {
                setCentralWidget(view);
    
                view->scene()->setSceneRect(0, 0, 100, 100);
                view->scene()->addItem(new QGraphicsRectItem{0, 0, 100, 100});
    
                auto item = new QGraphicsRectItem{0, 0, 50, 50};
                view->scene()->addItem(item);
                item->setFlag(QGraphicsItem::ItemIsMovable);
            }
    

    So now there is a rectangle indicating the sceneRect() area.

    Now I can observe tfor example he following effect:

    1. When I move the item to the right and outside the screenRect() at some point I no longer receive touch events. This does not happen when it is outside but still "close enough".
    2. If the item has not left the viewport() area and I move it back, i.e. close enough to the sceneRect() area I can again receive touch events
    3. Once the item has left the viewport() area I can no longer recover. That means after resizing the main widget so that I can grab the rectangle and moving it back has no observable effect.
    M Offline
    M Offline
    Michael Lehn
    wrote on last edited by
    #6

    For better keeping track where the effect stats I made the following changes:

    1. Class MyRectItem that prints the position after it has changed:
    class MyRectItem
        : public QGraphicsRectItem
    {
        public:
            MyRectItem(qreal x, qreal y, qreal width, qreal height,
                       QGraphicsItem *parent = nullptr)
                : QGraphicsRectItem{x, y, width, height, parent}
            {
                setFlag(QGraphicsItem::ItemSendsGeometryChanges);
            }
    
            QVariant itemChange(GraphicsItemChange change,
                                const QVariant &value) override
            {
                if (change == ItemPositionHasChanged) {
                    qDebug() << "item pos:" << pos();
                }
                return QGraphicsRectItem::itemChange(change, value);
            }
    
    };
    
    1. ... and this class is now used in the constructor of MainWindow:
    auto item = new MyRectItem{0, 0, 50, 50};
    view->scene()->addItem(item);
    

    Strangely I now never loose the touch events as long as the item is within the viewport() area. Even if it is outside the sceneRect() area.

    However, as before the touch evens are lost once the item was outside the viewport() area.

    M 1 Reply Last reply
    0
    • M Michael Lehn

      For better keeping track where the effect stats I made the following changes:

      1. Class MyRectItem that prints the position after it has changed:
      class MyRectItem
          : public QGraphicsRectItem
      {
          public:
              MyRectItem(qreal x, qreal y, qreal width, qreal height,
                         QGraphicsItem *parent = nullptr)
                  : QGraphicsRectItem{x, y, width, height, parent}
              {
                  setFlag(QGraphicsItem::ItemSendsGeometryChanges);
              }
      
              QVariant itemChange(GraphicsItemChange change,
                                  const QVariant &value) override
              {
                  if (change == ItemPositionHasChanged) {
                      qDebug() << "item pos:" << pos();
                  }
                  return QGraphicsRectItem::itemChange(change, value);
              }
      
      };
      
      1. ... and this class is now used in the constructor of MainWindow:
      auto item = new MyRectItem{0, 0, 50, 50};
      view->scene()->addItem(item);
      

      Strangely I now never loose the touch events as long as the item is within the viewport() area. Even if it is outside the sceneRect() area.

      However, as before the touch evens are lost once the item was outside the viewport() area.

      M Offline
      M Offline
      Michael Lehn
      wrote on last edited by
      #7

      @Michael-Lehn said in QGraphicsView and Qt::WA_AcceptTouchEvents:

      However, as before the touch evens are lost once the item was outside the viewport() area.

      To be more precise: I have to move the item outside the viewport() area. Drop it there. Only then I loose the touch events.

      I do not loose the events if I keep holding the item while moving it outside the viewport and back.

      A 1 Reply Last reply
      0
      • M Michael Lehn

        @Michael-Lehn said in QGraphicsView and Qt::WA_AcceptTouchEvents:

        However, as before the touch evens are lost once the item was outside the viewport() area.

        To be more precise: I have to move the item outside the viewport() area. Drop it there. Only then I loose the touch events.

        I do not loose the events if I keep holding the item while moving it outside the viewport and back.

        A Offline
        A Offline
        Asperamanca
        wrote on last edited by
        #8

        @Michael-Lehn
        The GraphicsView can only receive those touch event that are delivered to the parent widget of the viewport. In order to continue receiving events even when they happen outside of the widget area, you typically would grab the event (see e.g. QWidget::grabMouse or QGraphicsItem::grabMouse).

        Unfortunately, I am not aware of a way to grab low-level touch events in QWidgets/QGraphicsView directly. You might need to go via QWidget::grabGesture or QGraphicsObject::grabGesture, which would require defining your gesture in terms of QGestureManager.

        Alternatively, you could consider installing an application-level event filter, and handle the touch events on this low level, using your own logic to decide which widget (and thereby viewport) is supposed to receive which event.

        Neither solution sounds very simple or satisfying, I'm afraid.

        M 1 Reply Last reply
        0
        • A Asperamanca

          @Michael-Lehn
          The GraphicsView can only receive those touch event that are delivered to the parent widget of the viewport. In order to continue receiving events even when they happen outside of the widget area, you typically would grab the event (see e.g. QWidget::grabMouse or QGraphicsItem::grabMouse).

          Unfortunately, I am not aware of a way to grab low-level touch events in QWidgets/QGraphicsView directly. You might need to go via QWidget::grabGesture or QGraphicsObject::grabGesture, which would require defining your gesture in terms of QGestureManager.

          Alternatively, you could consider installing an application-level event filter, and handle the touch events on this low level, using your own logic to decide which widget (and thereby viewport) is supposed to receive which event.

          Neither solution sounds very simple or satisfying, I'm afraid.

          M Offline
          M Offline
          Michael Lehn
          wrote on last edited by Michael Lehn
          #9

          @Asperamanca I am not sure if I described my problem accurately. I am not interested in touch events that happen outside of the viewport. The problem is that the viewport suddenly does not receive any touch events once an item has left its area. It still receives all other kind of events (mouse and key events).

          IMHO this is a bug (either in my code or qt).

          A 1 Reply Last reply
          0
          • M Michael Lehn

            @Asperamanca I am not sure if I described my problem accurately. I am not interested in touch events that happen outside of the viewport. The problem is that the viewport suddenly does not receive any touch events once an item has left its area. It still receives all other kind of events (mouse and key events).

            IMHO this is a bug (either in my code or qt).

            A Offline
            A Offline
            Asperamanca
            wrote on last edited by
            #10

            @Michael-Lehn
            Do you receive touch events again after releasing and again touching into the viewport, after that mentioned item was moved out?

            M 1 Reply Last reply
            0
            • A Offline
              A Offline
              Asperamanca
              wrote on last edited by
              #11

              Ok, I tested your code on Windows (MSVC 2022 with Qt 6.5.2):
              I can drag the item out and back into the window, all the while receiving touch events. This could be a Mac issue. Maybe take a look if you find something here: https://bugreports.qt.io/issues

              1 Reply Last reply
              0
              • A Asperamanca

                @Michael-Lehn
                Do you receive touch events again after releasing and again touching into the viewport, after that mentioned item was moved out?

                M Offline
                M Offline
                Michael Lehn
                wrote on last edited by Michael Lehn
                #12

                @Asperamanca No, I do not. Once the item was dropped outside the viewport area I no longer receive any viewport event (but still mouse and key events).

                Thanks for testing! When you drag it out and back: Did you drop it in-between? I mean drag it out, drop it, resize the window so that you can see it again, and then drag it back?

                A 1 Reply Last reply
                0
                • M Michael Lehn

                  @Asperamanca No, I do not. Once the item was dropped outside the viewport area I no longer receive any viewport event (but still mouse and key events).

                  Thanks for testing! When you drag it out and back: Did you drop it in-between? I mean drag it out, drop it, resize the window so that you can see it again, and then drag it back?

                  A Offline
                  A Offline
                  Asperamanca
                  wrote on last edited by
                  #13

                  @Michael-Lehn
                  No, I tested with one long drag that goes beyond the window boundaries and back into the window. Is the other case something I should test, too?

                  M 1 Reply Last reply
                  0
                  • A Asperamanca

                    @Michael-Lehn
                    No, I tested with one long drag that goes beyond the window boundaries and back into the window. Is the other case something I should test, too?

                    M Offline
                    M Offline
                    Michael Lehn
                    wrote on last edited by
                    #14

                    @Asperamanca Yes, that would be great. Sorry for not stating this clear enough. Only when I drop the item outside the viewport I loose the viewport events. Without the drop everything is fine.

                    A 1 Reply Last reply
                    0
                    • M Michael Lehn

                      @Asperamanca Yes, that would be great. Sorry for not stating this clear enough. Only when I drop the item outside the viewport I loose the viewport events. Without the drop everything is fine.

                      A Offline
                      A Offline
                      Asperamanca
                      wrote on last edited by
                      #15

                      @Michael-Lehn Not sure the test setup is correct. I can move the item just as well with one finger (default move behavior, I guess), although I do not get into your viewport event handler then, of course.
                      I also added a timestamp to the qDebug() to see when I actually got events.

                      So....

                      • I can drag the item out of the window, and receive touch events until I release
                      • I can enlarge the window and see the item again
                      • I can start another drag operation on the item, and the viewport event recognizes it, and the item is dragged
                      M 1 Reply Last reply
                      0
                      • A Asperamanca

                        @Michael-Lehn Not sure the test setup is correct. I can move the item just as well with one finger (default move behavior, I guess), although I do not get into your viewport event handler then, of course.
                        I also added a timestamp to the qDebug() to see when I actually got events.

                        So....

                        • I can drag the item out of the window, and receive touch events until I release
                        • I can enlarge the window and see the item again
                        • I can start another drag operation on the item, and the viewport event recognizes it, and the item is dragged
                        M Offline
                        M Offline
                        Michael Lehn
                        wrote on last edited by
                        #16

                        Thanks, this helped me to understand better what actually goes wrong. I changed the code of MyView as follows:

                        class MyView
                            : public QGraphicsView
                        {
                            public:
                                MyView(QWidget *parent = nullptr)
                                    : QGraphicsView{parent}
                                {
                                    setScene(new QGraphicsScene);
                                    viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
                                }
                        
                                bool viewportEvent(QEvent *event) override
                                {
                                    qDebug() << "MyView::viewportEvent(QEvent *event)";
                                    switch (event->type()) {
                                        case QEvent::TouchBegin:
                                        case QEvent::TouchUpdate:
                                        case QEvent::TouchEnd:
                                            qDebug() << "Some touch event";
                                            return true;
                                        default:
                                            return QGraphicsView::viewportEvent(event);
                                    }
                                }
                        };
                        

                        So now I can distinguish between

                        • getting any viewportEvent at all
                        • and getting touch events in particular (here I no longer distinguish between 1 or 2 finger events)

                        Now I did the what you described:

                        @Asperamanca said in QGraphicsView and Qt::WA_AcceptTouchEvents:

                        • I can drag the item out of the window, and receive touch events until I release
                        • I can enlarge the window and see the item again
                        • I can start another drag operation on the item, and the viewport event recognizes it, and the item is dragged

                        First I get messages like

                        MyView::viewportEvent(QEvent *event)
                        Some touch event
                        MyView::viewportEvent(QEvent *event)
                        Some touch event
                        ...
                        

                        when I move the item around. Once the item was dropped outside the viewport I just get

                        MyView::viewportEvent(QEvent *event)
                        MyView::viewportEvent(QEvent *event)
                        ...
                        

                        So I actually still get viewport events. Except for touch events. It seems that touch events are now filtered out or no longer sent.

                        Moving the item around was never the problem. The problem is that I use touch events gestures for zooming.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved