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. QListView scrolls up on list item drop.

QListView scrolls up on list item drop.

Scheduled Pinned Locked Moved General and Desktop
9 Posts 3 Posters 4.2k 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.
  • A Offline
    A Offline
    alexoparin
    wrote on last edited by
    #1

    Hi guys.

    I read a couple of notes about enabling items reordering in the QListView. I reimplemented flags() and supportedDropActions() methods and it seems to be working. I can take an item from the list and drop it in another position and it moves their correctly except the listview itself scrolls to the very top as soon as I drop the item and the wrong item get's selected. Why doesn't it remember where it was before the drop? What I can do to solve this? And also where I should specify which item must be selected?

    Thanks for any help!

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      As for your problem, can you provide a minimal sample that reproduce the behavior ?

      Also, what version of Qt are you using ? On which OS ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • A Offline
        A Offline
        alexoparin
        wrote on last edited by
        #3

        It's Qt 5.2.0 on Windows 7. I'm using Ct Creator.
        What i did is:
        1) Added a List View using the disigner
        2) Then I set it properties:
        dragEnabled - true
        dragDropOverWriteMode - false
        dragDropOverMode - InternalMove
        defaultDropAction - MoveAction
        Scroll Modes - perItem
        movement - free or snap;

        *3) *I created a new class named PlayListModel inherited from QStingListModel
        @class PlayListModel : public QStringListModel
        {
        Q_OBJECT

        public:
        PlayListModel(QObject *parent) : QStringListModel(parent)
        {

        }
        Qt::ItemFlags flags(const QModelIndex &index) const;
        Qt::DropActions supportedDropActions() const    {        return Qt::CopyAction | Qt::MoveAction;    }
        int rowCount(const QModelIndex &parent) const;
        

        };

        Qt::ItemFlags PlayListModel::flags(const QModelIndex &index) const
        {
        if (index.isValid())
        {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
        }
        else
        {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
        }
        }

        int PlayListModel::rowCount(const QModelIndex &parent) const
        {
        if(parent.isValid())
        {
        return 0;
        }
        return stringList().length();
        }@

        *4) *In my mainwindow function I populate my model class with items
        @for(int i = 0; i < 25; i++)
        {
        QModelIndex index = playListsModel->index(i);
        playListsModel->setData(index, "Item"+QString::number(i+1));
        }@

        and then assign it to List View's model.

        @ui->listsView->setModel(playListsModel); @

        Run the program and get such a behaviour.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          alexoparin
          wrote on last edited by
          #4

          Interesting. It happens only when the list widget or list view are created in the designer. If I create it in code and just
          @setDragDropMode(QAbstractItemView::InternalMove);@
          then it works as I want it to... hmm.

          Where's the bug?
          Is it the compiler or ide problem?? Or just some parameter I missed somewhere in the designer or maybe the defaults in the designer differ from those in the framework itself?

          I still can't make it work via the designer.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Sounds strange indeed

            Can you compare the values of these properties for both widgets ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • A Offline
              A Offline
              alexoparin
              wrote on last edited by
              #6

              The same.... Actually I found out that it has nothing to do with the designer and only happens to QListView. I added both QListWidget and QListView to the layout. Added several items to QListWidget and then set the QListView's model to QListWidget::model();
              Then I set both's
              @plistWidget->setDragDropMode(QAbstractItemView::InternalMove);
              plistView->setDragDropMode(QAbstractItemView::InternalMove);@
              and what I get is that QListWidget works properly (it does'n scroll anywhere, and the moved item stays selected) but QListView doesn't behave the same way (it scrolls to top and selects eithe the index item used to be at or the one right next to where it was depending on moving the item up or down the list).
              Seem like I just don't know something about it but I can't find the answer to this.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                QListWidget reimplements the dropEvent method so it might be that.

                Did you have a look at the "bug report system":http://bugreports.qt-project.org ? Somebody might already have posted something about it, if not you could consider open a new bug report providing a minimal compilable example that show the behavior

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Bugreport "here":https://bugreports.qt-project.org/browse/QTBUG-36610

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    Kogotoro
                    wrote on last edited by Kogotoro
                    #9

                    actual in qt5.11
                    it seem what glitch happens within
                    QAbstractItemView::rowsAboutToBeRemoved
                    or so...

                    QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
                        {
                            Q_D(QAbstractItemView);
                            setState(CollapsingState);
                    ....
                    

                    CollapsingState... for qlistview ???

                    workaround for some cases

                    class listviewscrollfix: public QListView{...}
                    
                    void listviewscrollfix::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
                    {
                    //    Q_D(QListView);
                    //    // if the parent is above d->root in the tree, nothing will happen
                        ///QAbstractItemView::rowsAboutToBeRemoved(parent, start, end);
                        {
                            //Q_D(QAbstractItemView);
                            setState(NoState);/// !!! CollapsingState ///main glitch reason 
                            // Ensure one selected item in single selection mode.
                            QModelIndex current = currentIndex();
                            if (selectionMode() == SingleSelection
                                && current.isValid()
                                && current.row() >= start
                                && current.row() <= end
                                && current.parent() == parent) {
                                int totalToRemove = end - start + 1;
                                if (model()->rowCount(parent) <= totalToRemove) { // no more children
                                    QModelIndex index = parent;
                    ///we dont have access to some metods so skipped
                    //                while (index != d->root && !d->isIndexEnabled(index))
                    //                    index = index.parent();
                    //                if (index != d->root)
                                        setCurrentIndex(index);
                                } else {
                                    ///we dont have access to some metods so skipped
                    //                int row = end + 1;
                    //                QModelIndex next;
                    //                do { // find the next visible and enabled item
                    //                    next = d->model->index(row++, current.column(), current.parent());
                    //                } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
                    //                if (row > d->model->rowCount(parent)) {
                    //                    row = start - 1;
                    //                    do { // find the previous visible and enabled item
                    //                        next = d->model->index(row--, current.column(), current.parent());
                    //                    } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
                    //                }
                    //                setCurrentIndex(next);
                                }
                            }
                            ///we dont have access to some metods & and our list not editable so skipped
                            // Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
                    //        QEditorIndexHash::iterator i = d->editorIndexHash.begin();
                    //        while (i != d->editorIndexHash.end()) {
                    //            const QModelIndex index = i.value();
                    //            if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
                    //                QWidget *editor = i.key();
                    //                QEditorInfo info = d->indexEditorHash.take(index);
                    //                i = d->editorIndexHash.erase(i);
                    //                if (info.widget)
                    //                    d->releaseEditor(editor, index);
                    //            } else {
                    //                ++i;
                    //            }
                    //        }
                        }
                        ///we dont have access to some metods & we dont have hidden rows so skipped
                    //    if (parent == d->root) {
                    //        QSet<QPersistentModelIndex>::iterator it = d->hiddenRows.begin();
                    //        while (it != d->hiddenRows.end()) {
                    //            int hiddenRow = it->row();
                    //            if (hiddenRow >= start && hiddenRow <= end) {
                    //                it = d->hiddenRows.erase(it);
                    //            } else {
                    //                ++it;
                    //            }
                    //        }
                    //    }
                    //    d->clear();//???
                    //    d->doDelayedItemsLayout();
                    }
                    

                    or just

                    void listviewscrollfix::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end){}
                    

                    and

                    bool SomeListModel::removeRows(int row, int count, const QModelIndex &parent)
                    {
                        if (parent.isValid())
                            return false;
                    ...
                        for (int i = 0; i != count; ++i){
                    ...
                                beginRemoveRows(parent, row, row);
                            someitemcontainer.removeAt(row);//for small listst it will be ok 1 by 1
                                endRemoveRows();
                                dataChanged(index(row),index(row));//scroll glitch workaround...dont ask why so...//for update scrollbar max value
                    ...
                        }
                        return true;
                    }
                    
                    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