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. Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows
Forum Updated to NodeBB v4.3 + New Features

Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 2 Posters 3.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.
  • DiracsbracketD Offline
    DiracsbracketD Offline
    Diracsbracket
    wrote on last edited by
    #1

    Hi,
    I am experiencing the same "bug" as in this report:
    https://bugreports.qt.io/browse/QTBUG-5115

    If a subclass of QAbstractItemView is configured with autoscroll(true) and the selection mode select the whole row on selection, the autoscrolling should not scroll horizontally. The row are considered as a single entity so scrolling horizontally is a strange behavior.

    A proposed workaround is given in the same report basically as:

    a) setAutoScroll(false) by default
    b) derive from QTreeView, reimplement startDrag and wrap a call to drag->exec like this:
    setAutoScroll ( true );
    drag->exec ( supportedActions );
    setAutoScroll ( false );

    I have tried to copy the existing code from QAbstractItemView::startDrag() and just added the two wrapper lines ending with the \\HACK comment as below:

    void TreeView::startDrag(Qt::DropActions supportedActions)
    {
        Q_D(QAbstractItemView);
    
        QModelIndexList indexes = d->selectedDraggableIndexes();
        if (indexes.count() > 0) {
            QMimeData *data = d->model->mimeData(indexes);
            if (!data)
                return;
            QRect rect;
            QPixmap pixmap = d->renderToPixmap(indexes, &rect);
            rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
            QDrag *drag = new QDrag(this);
            drag->setPixmap(pixmap);
            drag->setMimeData(data);
            drag->setHotSpot(d->pressedPosition - rect.topLeft());
            Qt::DropAction defaultDropAction = Qt::IgnoreAction;
    
            if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
                defaultDropAction = d->defaultDropAction;
            else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                defaultDropAction = Qt::CopyAction;
    
            setAutoScroll(true); //HACK
    
            if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
                d->clearOrRemove();
    
            setAutoScroll(false); //HACK
    
            // Reset the drop indicator
            d->dropIndicatorRect = QRect();
            d->dropIndicatorPosition = OnItem;
        }
    }
    

    However, this does not compile, producing all these errors:
    0_1509110971058_295695ea-08cf-417b-8a02-267fb35fa53e-image.png

    How do I go about implementing the proposed hack in the BUG report?

    raven-worxR 1 Reply Last reply
    0
    • DiracsbracketD Diracsbracket

      Hi,
      I am experiencing the same "bug" as in this report:
      https://bugreports.qt.io/browse/QTBUG-5115

      If a subclass of QAbstractItemView is configured with autoscroll(true) and the selection mode select the whole row on selection, the autoscrolling should not scroll horizontally. The row are considered as a single entity so scrolling horizontally is a strange behavior.

      A proposed workaround is given in the same report basically as:

      a) setAutoScroll(false) by default
      b) derive from QTreeView, reimplement startDrag and wrap a call to drag->exec like this:
      setAutoScroll ( true );
      drag->exec ( supportedActions );
      setAutoScroll ( false );

      I have tried to copy the existing code from QAbstractItemView::startDrag() and just added the two wrapper lines ending with the \\HACK comment as below:

      void TreeView::startDrag(Qt::DropActions supportedActions)
      {
          Q_D(QAbstractItemView);
      
          QModelIndexList indexes = d->selectedDraggableIndexes();
          if (indexes.count() > 0) {
              QMimeData *data = d->model->mimeData(indexes);
              if (!data)
                  return;
              QRect rect;
              QPixmap pixmap = d->renderToPixmap(indexes, &rect);
              rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
              QDrag *drag = new QDrag(this);
              drag->setPixmap(pixmap);
              drag->setMimeData(data);
              drag->setHotSpot(d->pressedPosition - rect.topLeft());
              Qt::DropAction defaultDropAction = Qt::IgnoreAction;
      
              if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
                  defaultDropAction = d->defaultDropAction;
              else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                  defaultDropAction = Qt::CopyAction;
      
              setAutoScroll(true); //HACK
      
              if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction)
                  d->clearOrRemove();
      
              setAutoScroll(false); //HACK
      
              // Reset the drop indicator
              d->dropIndicatorRect = QRect();
              d->dropIndicatorPosition = OnItem;
          }
      }
      

      However, this does not compile, producing all these errors:
      0_1509110971058_295695ea-08cf-417b-8a02-267fb35fa53e-image.png

      How do I go about implementing the proposed hack in the BUG report?

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Diracsbracket
      you cannot simply copy and paste method implementations from Qt source code.
      Since they are using private classes (Q_D(...) macro).
      The startDrag() method isn't that complicated and can mostly be reimplemented. You need to do so and replace all method calls to the d-pointer with your custom implementations.

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      DiracsbracketD 2 Replies Last reply
      1
      • raven-worxR raven-worx

        @Diracsbracket
        you cannot simply copy and paste method implementations from Qt source code.
        Since they are using private classes (Q_D(...) macro).
        The startDrag() method isn't that complicated and can mostly be reimplemented. You need to do so and replace all method calls to the d-pointer with your custom implementations.

        DiracsbracketD Offline
        DiracsbracketD Offline
        Diracsbracket
        wrote on last edited by
        #3

        @raven-worx said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

        you cannot simply copy and paste method implementations from Qt source code.

        Well, since this is a virtual method, I just thought I could use exactly the same code in a derived class, but apparently not. I didn't know about the D pointer, so thanks.

        And yes, nothing is difficult, if you know how.

        1 Reply Last reply
        0
        • raven-worxR raven-worx

          @Diracsbracket
          you cannot simply copy and paste method implementations from Qt source code.
          Since they are using private classes (Q_D(...) macro).
          The startDrag() method isn't that complicated and can mostly be reimplemented. You need to do so and replace all method calls to the d-pointer with your custom implementations.

          DiracsbracketD Offline
          DiracsbracketD Offline
          Diracsbracket
          wrote on last edited by Diracsbracket
          #4

          @raven-worx said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

          You need to do so and replace all method calls to the d-pointer with your custom implementations

          If it's that easy, can you show me how to do it? How can I reimplement the call to e.g. d->selectedDraggableIndexes(); or worse, d->model->mimeData(indexes);?

          raven-worxR 1 Reply Last reply
          0
          • DiracsbracketD Diracsbracket

            @raven-worx said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

            You need to do so and replace all method calls to the d-pointer with your custom implementations

            If it's that easy, can you show me how to do it? How can I reimplement the call to e.g. d->selectedDraggableIndexes(); or worse, d->model->mimeData(indexes);?

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by raven-worx
            #5

            @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

            Well, since this is a virtual method, I just thought I could use exactly the same code in a derived class, but apparently not

            virtual methods are only only tell that they are derivable. But for their contents the general visibility rules apply. The d-pointer is private and thus only accessible in this class (or it's friend classes).

            @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

            How can I reimplement the call to e.g. d->selectedDraggableIndexes(); or worse, d->model->mimeData(indexes);?

            see the implementation of this method. Basically it's just getting a list of all selected indexes and remove the ones which are not drag enabled (by inspecting their item flags)

            The model is already available via the public interface (QAbstractItemView::model()), so no problem there.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            DiracsbracketD 1 Reply Last reply
            0
            • raven-worxR raven-worx

              @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

              Well, since this is a virtual method, I just thought I could use exactly the same code in a derived class, but apparently not

              virtual methods are only only tell that they are derivable. But for their contents the general visibility rules apply. The d-pointer is private and thus only accessible in this class (or it's friend classes).

              @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

              How can I reimplement the call to e.g. d->selectedDraggableIndexes(); or worse, d->model->mimeData(indexes);?

              see the implementation of this method. Basically it's just getting a list of all selected indexes and remove the ones which are not drag enabled (by inspecting their item flags)

              The model is already available via the public interface (QAbstractItemView::model()), so no problem there.

              DiracsbracketD Offline
              DiracsbracketD Offline
              Diracsbracket
              wrote on last edited by Diracsbracket
              #6

              @raven-worx said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

              The model is already available via the public interface (QAbstractItemView::model())

              Yes, that one is easy. The others are less straight forward.
              Anyway... This is way too much hassle for what should have been a simple setting to distinguish between vertical autoscroll and horizontal autoscroll.

              I will just try to intercept the selection change, and override the selected column to 0.

              raven-worxR 1 Reply Last reply
              0
              • DiracsbracketD Diracsbracket

                @raven-worx said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

                The model is already available via the public interface (QAbstractItemView::model())

                Yes, that one is easy. The others are less straight forward.
                Anyway... This is way too much hassle for what should have been a simple setting to distinguish between vertical autoscroll and horizontal autoscroll.

                I will just try to intercept the selection change, and override the selected column to 0.

                raven-worxR Offline
                raven-worxR Offline
                raven-worx
                Moderators
                wrote on last edited by
                #7

                @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

                I will just try to intercept the selection change, and override the selected column to 0.

                you may want to look at QAbstractItemView::selectionCommand() then.
                I am not sure if it is also called in for your case, but in general this method is called before the actual selection change happens. Thus you can prevent a "jumping effect" in your GUI.

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                DiracsbracketD 1 Reply Last reply
                1
                • raven-worxR raven-worx

                  @Diracsbracket said in Disabling horizontal autoscroll of QTreeView when selectionBehavior is SelectRows:

                  I will just try to intercept the selection change, and override the selected column to 0.

                  you may want to look at QAbstractItemView::selectionCommand() then.
                  I am not sure if it is also called in for your case, but in general this method is called before the actual selection change happens. Thus you can prevent a "jumping effect" in your GUI.

                  DiracsbracketD Offline
                  DiracsbracketD Offline
                  Diracsbracket
                  wrote on last edited by
                  #8

                  @raven-worx Cheers!

                  DiracsbracketD 1 Reply Last reply
                  0
                  • DiracsbracketD Diracsbracket

                    @raven-worx Cheers!

                    DiracsbracketD Offline
                    DiracsbracketD Offline
                    Diracsbracket
                    wrote on last edited by
                    #9

                    I found an even lazier method, as I just realized that the autoscroll does not happen if I don't use the resizeColumnToContents() method on the columns.

                    In that case, even when clicking on an item with truncated text, the list won't scroll horizontally, unless the viewport width is below some value it seems.
                    I will just settle with this for now.

                    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