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. Is it possible with QScrollArea behave like a wheel?
Forum Updated to NodeBB v4.3 + New Features

Is it possible with QScrollArea behave like a wheel?

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 2 Posters 674 Views 2 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.
  • T Offline
    T Offline
    TheoSys
    wrote on last edited by
    #1

    I created a custom scroll area by using QScrollArea which is working quite nice. It is possible to scroll the content by wishing with a finger on a touch display or dragging with the mouse on a desktop. The scroll area has no visible scrollbars. This is what I want.
    But I can not scroll over the top or bottom item or the left or right item inside. Is it possible to make a scroll area that behaves like a wheel so that I can turn it around and around? If so, how?

    2cf948fe-b1d0-40b3-831b-46e7d7299a44-grafik.png
    Another question is about the scrolling. Is it possible to implement smooth scrolling? I mean when I call the function QScrollBar::setSliderPosition() or QScrollArea::ensureWidgetVisible() that it scrolls slowly to the wanted position and not suddenly, like it does currently?

    A.T.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      CPPUIX
      wrote on last edited by
      #2

      I have a few questions, and I think answering them would clarify a lot about what you need:

      • Do you mean infinite horizontal and vertical scrolling?

      • What widget are you using inside your scroll area?

      • Wouldn't it be better if you made a separate topic for your second question? I think the first one is a big task on its own, so let's focus on it first.

      Possibly related sources:

      • infinite scrolling of a tableview

      • Infinite scrolling of a qt listView in QML

      T 1 Reply Last reply
      0
      • C CPPUIX

        I have a few questions, and I think answering them would clarify a lot about what you need:

        • Do you mean infinite horizontal and vertical scrolling?

        • What widget are you using inside your scroll area?

        • Wouldn't it be better if you made a separate topic for your second question? I think the first one is a big task on its own, so let's focus on it first.

        Possibly related sources:

        • infinite scrolling of a tableview

        • Infinite scrolling of a qt listView in QML

        T Offline
        T Offline
        TheoSys
        wrote on last edited by
        #3

        @Abderrahmene_Rayene :
        Yes, I mean infinite scrolling.
        If you look at the screen shot above, then one of the time elements consist of a QWidget (I call this an item) and this QWidget contains 1 or more QLabel. So in this example the QWidget has 9 QLabel childs. On the left side the background is one, each time part (11, AM, 00, 30) is one and each of the lines on the right of the time is a QLabel. To be later able to identify them on a mouse click, each element has a distinct name. So far so well.
        Each of this "items" is placed on another QWidget. This parent Qwidget is as large as all the "items" together. So the QScrollArea has this main QWidget, which has the "items" as childs.

            QScrollArea::setParent(mParent);
            QScrollArea::setFixedSize(mWidth, mHeight);
            setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
            setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
            // Set a transparent background
            QPalette palette(this->palette());
            palette.setColor(QPalette::Window, QColor(Qt::transparent));
            setPalette(palette);
        
            mMain = new QWidget(this);   // QWidget *mMain;
            mMain->move(0, 0);
            mMain->setContentsMargins(0, 0, 0, 0);
            setFixedSize(mWidth, mHeight);
            setWidget(mMain);
            mHLayout = new QHBoxLayout(mMain);   // QHBoxLayout *mHLayout;
            mHLayout->setSpacing(0);
            mHLayout->setContentsMargins(0, 0, 0, 0);
        

        The above code is a shortened excerpt of the initialization of my class called TQScrollArea.

        class TQScrollArea : public QScrollArea
        {
            Q_OBJECT
        
            public:
                TQScrollArea();
                TQScrollArea(QWidget *parent);
                TQScrollArea(QWidget *parent, int w, int h, bool vertical = false);
                TQScrollArea(QWidget *parent, const QSize& size, bool vertical = false);
                ~TQScrollArea();
        [...]
        

        Doing it this way, I found no way for infinite scrolling.

        A.T.

        C 1 Reply Last reply
        0
        • T TheoSys

          @Abderrahmene_Rayene :
          Yes, I mean infinite scrolling.
          If you look at the screen shot above, then one of the time elements consist of a QWidget (I call this an item) and this QWidget contains 1 or more QLabel. So in this example the QWidget has 9 QLabel childs. On the left side the background is one, each time part (11, AM, 00, 30) is one and each of the lines on the right of the time is a QLabel. To be later able to identify them on a mouse click, each element has a distinct name. So far so well.
          Each of this "items" is placed on another QWidget. This parent Qwidget is as large as all the "items" together. So the QScrollArea has this main QWidget, which has the "items" as childs.

              QScrollArea::setParent(mParent);
              QScrollArea::setFixedSize(mWidth, mHeight);
              setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
              setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
              // Set a transparent background
              QPalette palette(this->palette());
              palette.setColor(QPalette::Window, QColor(Qt::transparent));
              setPalette(palette);
          
              mMain = new QWidget(this);   // QWidget *mMain;
              mMain->move(0, 0);
              mMain->setContentsMargins(0, 0, 0, 0);
              setFixedSize(mWidth, mHeight);
              setWidget(mMain);
              mHLayout = new QHBoxLayout(mMain);   // QHBoxLayout *mHLayout;
              mHLayout->setSpacing(0);
              mHLayout->setContentsMargins(0, 0, 0, 0);
          

          The above code is a shortened excerpt of the initialization of my class called TQScrollArea.

          class TQScrollArea : public QScrollArea
          {
              Q_OBJECT
          
              public:
                  TQScrollArea();
                  TQScrollArea(QWidget *parent);
                  TQScrollArea(QWidget *parent, int w, int h, bool vertical = false);
                  TQScrollArea(QWidget *parent, const QSize& size, bool vertical = false);
                  ~TQScrollArea();
          [...]
          

          Doing it this way, I found no way for infinite scrolling.

          A.T.

          C Offline
          C Offline
          CPPUIX
          wrote on last edited by CPPUIX
          #4

          @TheoSys I have an idea that might work for you or at lease inspire you.

          If you scroll down: remove the top item in your layout and insert it at the end.

          If you scroll up: remove the bottom item in your layout and insert it at the beginning.

          But only if you scroll as much as an object's height.

          I implemented this using a custom QScrollArea and 9 buttons from 0 to 9, and overrode the scrollArea's wheelEvent to achieve infinite scrolling.

          Here's the code with some "documentation"

          //This function overrides the one of QScrollArea class in your subclass of it
          void TQScrollArea::wheelEvent(QWheelEvent *e)
          {
              //get scrollArea's widget
              QWidget *widget = this->widget();
              //get scrollArea's widget's layout
              QVBoxLayout *layout = this->findChild<QVBoxLayout *>("layout",Qt::FindChildrenRecursively);
          
              //This is for when we move mouse wheel forward
              if(e->angleDelta().y()>0)
              {
                  //get one of your layout's objects to use its height later on
                  QPushButton *b = this->findChild<QPushButton *>("button9",Qt::FindChildrenRecursively);
          
                  //This next if block is just to enable me to scroll with the mouse wheel since there are no scrollbars
                  if(widget->visibleRegion().boundingRect().y()-10>=0)
                      this->viewport()->scroll(0,10);
          
                  //This if statement detects if we have scrolled as much as an object's height
                  //so if you're not going to use a wheel event, you can use the same idea in a drag or mousemove event
                  //use your scrollArea's widget's visible region y coordinate to detect how much it moved
                  if(widget->visibleRegion().boundingRect().y()-10<=b->height())
                  {
                      //If true then we remove the the last item in layout
                      auto whatisthis = layout->itemAt(layout->count()-1);
                      layout->removeItem(layout->itemAt(layout->count()-1));
                      //then insert it at the beginning
                      layout->insertItem(0,whatisthis);
                  }
              }
              //This is for when we move mouse wheel backwards
              if(e->angleDelta().y()<0)
              {
                  //Here we do the same except we remove the first item and insert it at the end of the layout
                  QPushButton *b = this->findChild<QPushButton *>("button1",Qt::FindChildrenRecursively);
                  if(widget->visibleRegion().boundingRect().y()+10<=layout->geometry().height()-b->height()*7.8)
                  {
                      this->viewport()->scroll(0,-10);
                  }
                  if(widget->visibleRegion().boundingRect().y()+10<=b->height())
                  {
                      auto whatisthis = layout->itemAt(0);
                      layout->removeItem(layout->itemAt(0));
                      layout->insertItem(layout->count(),whatisthis);
                  }
              }
              //et voila, this creates the infinite scrolling effect, it's not perfect or organized, but it does the trick
              //and you have to adjut it to your use case, because this is just an example to demonstrate my idea
          }
          
          

          This is how it looks like:

          infiniteScroll.gif

          This not exactly your case because I don't know how exactly you're scrolling so I went with mouse wheel, but I think you just need to adapt it to yours.

          If you have any questions don't hesitate to ask, my workarounds are confusing.

          T 1 Reply Last reply
          0
          • C CPPUIX

            @TheoSys I have an idea that might work for you or at lease inspire you.

            If you scroll down: remove the top item in your layout and insert it at the end.

            If you scroll up: remove the bottom item in your layout and insert it at the beginning.

            But only if you scroll as much as an object's height.

            I implemented this using a custom QScrollArea and 9 buttons from 0 to 9, and overrode the scrollArea's wheelEvent to achieve infinite scrolling.

            Here's the code with some "documentation"

            //This function overrides the one of QScrollArea class in your subclass of it
            void TQScrollArea::wheelEvent(QWheelEvent *e)
            {
                //get scrollArea's widget
                QWidget *widget = this->widget();
                //get scrollArea's widget's layout
                QVBoxLayout *layout = this->findChild<QVBoxLayout *>("layout",Qt::FindChildrenRecursively);
            
                //This is for when we move mouse wheel forward
                if(e->angleDelta().y()>0)
                {
                    //get one of your layout's objects to use its height later on
                    QPushButton *b = this->findChild<QPushButton *>("button9",Qt::FindChildrenRecursively);
            
                    //This next if block is just to enable me to scroll with the mouse wheel since there are no scrollbars
                    if(widget->visibleRegion().boundingRect().y()-10>=0)
                        this->viewport()->scroll(0,10);
            
                    //This if statement detects if we have scrolled as much as an object's height
                    //so if you're not going to use a wheel event, you can use the same idea in a drag or mousemove event
                    //use your scrollArea's widget's visible region y coordinate to detect how much it moved
                    if(widget->visibleRegion().boundingRect().y()-10<=b->height())
                    {
                        //If true then we remove the the last item in layout
                        auto whatisthis = layout->itemAt(layout->count()-1);
                        layout->removeItem(layout->itemAt(layout->count()-1));
                        //then insert it at the beginning
                        layout->insertItem(0,whatisthis);
                    }
                }
                //This is for when we move mouse wheel backwards
                if(e->angleDelta().y()<0)
                {
                    //Here we do the same except we remove the first item and insert it at the end of the layout
                    QPushButton *b = this->findChild<QPushButton *>("button1",Qt::FindChildrenRecursively);
                    if(widget->visibleRegion().boundingRect().y()+10<=layout->geometry().height()-b->height()*7.8)
                    {
                        this->viewport()->scroll(0,-10);
                    }
                    if(widget->visibleRegion().boundingRect().y()+10<=b->height())
                    {
                        auto whatisthis = layout->itemAt(0);
                        layout->removeItem(layout->itemAt(0));
                        layout->insertItem(layout->count(),whatisthis);
                    }
                }
                //et voila, this creates the infinite scrolling effect, it's not perfect or organized, but it does the trick
                //and you have to adjut it to your use case, because this is just an example to demonstrate my idea
            }
            
            

            This is how it looks like:

            infiniteScroll.gif

            This not exactly your case because I don't know how exactly you're scrolling so I went with mouse wheel, but I think you just need to adapt it to yours.

            If you have any questions don't hesitate to ask, my workarounds are confusing.

            T Offline
            T Offline
            TheoSys
            wrote on last edited by
            #5

            @Abderrahmene_Rayene :
            Thank you for your answer. I understood how you did it and this is indeed a way I can implement it. But it shows also that there is no infinite scroll build in into Qt. I hoped to not have to implement it myself but hope dies last.

            A.T.

            C 1 Reply Last reply
            0
            • T TheoSys has marked this topic as solved on
            • T TheoSys

              @Abderrahmene_Rayene :
              Thank you for your answer. I understood how you did it and this is indeed a way I can implement it. But it shows also that there is no infinite scroll build in into Qt. I hoped to not have to implement it myself but hope dies last.

              A.T.

              C Offline
              C Offline
              CPPUIX
              wrote on last edited by CPPUIX
              #6

              @TheoSys What if this feature gets suggested?
              Although the only way that I found to do that is by using the bug report system.
              But then I suspect it would be shut down as "user can implement this themselves".

              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