Srolling through QListView items without any mouse move event!



  • I have a QListView which contains QStandardItems. When I drag an item on one of the QStandardItems (first or last which is currently visible to the user), the scroll bar should move backward/forward making the items scroll without any mouse move event. I mean when a place the cursor on first or last item visible, the items should be scrolled.



  • you should use QListView::verticalScrollBar->setValue(currentValue + heightOfQStandardItem);


  • Moderators

    use this code in your derived class' QAbstractItemView::viewportEvent() ... or use an eventFilter on the viewport if you don't want to subclass:
    @
    void MyView::viewportEvent ( QEvent * event )
    {
    if( event->type() == QEvent::DragMove )
    {
    QModelIndex index = view->indexAt(event->pos());
    if( index.isValid() )
    {
    QRect visualRect = view->visualRect(index);
    QRect viewportRect = view->viewport()->rect();
    if( (viewportRect | visualRect) != viewportRect ) //index is currently not completely visible
    view->scrollTo(index);
    }
    }
    QListView::viewportEvent(event);
    }
    @



  • List view does it by default. If you drag an element and stop over last one (or edge of viewport) list view will start scrolling after less than a second.
    When you subclass some class and reimplement virtual methods you actually lost it's previous functionality. Especially when you sublcass widgets you somehow break it's inner state. It is important to call parent method from within your class to get it back.

    This example works for me.

    @
    void CustomListView::dragEnterEvent(QDragEnterEvent * event)
    {
    if (event is mine) {
    event->acceptProposedAction();
    }
    else QListView::dragEnterEvent(event);
    }

    void CustomListView::dropEvent(QDropEvent * event)
    {
    if (event is mine) {
    event->acceptProposedAction();
    }
    else QListView::dropEvent(event);
    }

    void CustomListView::dragMoveEvent(QDragMoveEvent * event)
    {
    QListView::dragMoveEvent(event);
    if (event is mine) {
    event->acceptProposedAction();
    }
    }

    void CustomListView::mousePressEvent(QMouseEvent * event)
    {
    if (event->button() == Qt::LeftButton)
    _dragPos = event->pos();
    QListView::mousePressEvent(event);
    }

    void QDropBoxListView::mouseMoveEvent(QMouseEvent * event)
    {
    if (event->buttons() & Qt::LeftButton) {
    if ((event->pos() - _dragPos).manhattanLength()
    >= QApplication::startDragDistance()) {
    //start my custom drag
    }
    }
    QListView::mouseMoveEvent(event);
    }
    @



  • Thanks a lot!!! It worked...

    [quote author="raven-worx" date="1371017854"]use this code in your derived class' QAbstractItemView::viewportEvent() ... or use an eventFilter on the viewport if you don't want to subclass: @ void MyView::viewportEvent ( QEvent * event ) { if( event->type() == QEvent::DragMove ) { QModelIndex index = view->indexAt(event->pos()); if( index.isValid() ) { QRect visualRect = view->visualRect(index); QRect viewportRect = view->viewport()->rect(); if( (viewportRect | visualRect) != viewportRect ) //index is currently not completely visible view->scrollTo(index); } } QListView::viewportEvent(event); } @[/quote]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.