Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. ListView: Long press and release to initiate a grab, move mouse to scroll, then click to release
Forum Updated to NodeBB v4.3 + New Features

ListView: Long press and release to initiate a grab, move mouse to scroll, then click to release

Scheduled Pinned Locked Moved QML and Qt Quick
8 Posts 4 Posters 7.6k Views 1 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 Offline
    M Offline
    mbarclaygmail.com
    wrote on last edited by
    #1

    Hello,

    I am trying to figure out how to change the way ListView responds to mouse events. I have a large, scrollable list, and I want to "long press" on the ListView widget to initiate scrolling. After the long press (and release), the list is "grabbed" and any movement of the mouse along the y-axis should result in scrolling of the List. A single click should release grabbed list.

    Is this possible?

    Thanks,
    Matt

    1 Reply Last reply
    0
    • D Offline
      D Offline
      DenisKormalev
      wrote on last edited by
      #2

      I think that it is possible only by custom plugin with class inherited from listview (or maybe from flickable). Not sure, but I'll be at your place I will start from this point while solving this issue.

      1 Reply Last reply
      0
      • 2 Offline
        2 Offline
        2beers
        wrote on last edited by
        #3

        I think you should look at the Flickable scrollbar example( I can't find the link now but is somewhere in docs) . after the long press action you scroll your flickable element(I think it will work for listview) on y-axis based on your mouse position.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DenisKormalev
          wrote on last edited by
          #4

          2beers, hm, can't find how to track mouse without buttons pressed

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mbarclaygmail.com
            wrote on last edited by
            #5

            Hmm, I thought I was being clever, but this doesn't work. When I try to set grabMouse() on the ListView, the program crashes. On the MouseArea, QGraphics complains there is no scene.

            @class MySystem : public QObject
            {
            Q_OBJECT
            Q_INVOKABLE void grabMouse(QDeclarativeItem *item) { if(item) item->grabMouse(); }
            };

            int main(void)
            {
            ...
            ...
            view.rootContext()->setContextProperty("mysys", new MySystem());
            }

            QML

            Item {
            ListModel { id: myModel; ListElement { type: "Dog"; age: 8 } ListElement { type: "Dog"; age: 8 } }
            Component { id: myDelegate; Text { text: type + ", " + age } }
            ListView {
            id: myList
            model: myModel
            delegate: myDelegate
            MouseArea {
            id: mymouse
            anchors.fill: parent
            onPressAndHold: {
            // This crashes:
            mysys.grabMouse(myList);

                        // This complains:  QGraphicsItem::grabMouse: cannot grab mouse without scene
                        // mysys.grabMouse(mymouse);
               
                        // This complains: QGraphicsItem::grabMouse: cannot grab mouse while invisible
                        // mysys.grabMouse(listItem)
                 }
              }
            

            }
            }
            @

            1 Reply Last reply
            0
            • M Offline
              M Offline
              mbarclaygmail.com
              wrote on last edited by
              #6

              Thinking out loud here, I could create a MouseGrabArea class similar to MouseArea...

              No idea if something like this would work, but will try tomorrow:

              @ListView {
              id: mylist

              MouseGrabArea { height: parent.height; width: parent.width; }
              ...
              ...
              }

              // Psuedo code...
              class MouseGrabArea : public QDeclarativeItem
              {
              public slot:
              void onMousePress() { m_press_time = gettime(); } // Time in milliseconds
              void onMouseRelease() { if(gettime() - m_press_time > 800) { this.grabMouse(); } else { this.releaseMouse(); } }
              };
              @

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mbrasser
                wrote on last edited by
                #7

                Hi,

                Are you looking for standard "flicking" behavior after the long press, or just panning? If the latter, putting a MouseArea over the ListView, and using it to manually manipulate the ListView's position (using e.g. positionViewAtIndex, or contextX/Y) might work.

                Regards,
                Michael

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  mbarclaygmail.com
                  wrote on last edited by
                  #8

                  I solved this with a little help from C++. Using rootContext->setContextProperty(), I created a C++ class with Q_INVOKABLE methods that:

                  @setGrabCursor(bool doit) const
                  {
                  if(doit)
                  QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor));
                  else
                  QApplication::restoreOverrideCursor();
                  }@

                  From my app, when I detect a long press on my ListView delegate, I call setGrabCursor(true) and make a full screen mousearea active that marks mouse events as accepted. I tie the mouse y coordinate to the listview contentY inside of a onPositionChanged() handler. On single click of the mousearea, I call setGrabCursor(false).

                  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