Positioning a resizable widget inside a scroll areaQGraphicsItem::setTransformOriginPoint bug when trying to scale imageHow does a Qt custom widget notify ScrollArea parent about change of viewresize problem in scroll areaQWidget is not showing up on entire screenUnwanted margin inside QGraphicsView with ScrollbarsNothing showing up in QScrollAreaScale a QGraphicsView without Scaling a QWidget that has been added to itHow to use QML Scale Element for incremental scaling with different originScaling a rotated item based on top left moves the itemMove QGraphicsView top left to a certain point in QGraphicsScene manually

Start job from another SQL server instance

A factorization game

Endgame puzzle: How to avoid stalemate and win?

Notation: What does the tilde bellow of the Expectation mean?

How to pass hash as password to ssh server

Nested loops to process groups of pictures

Formatting Datetime.now()

What do "Sech" and "Vich" mean in this sentence?

Hostile Divisor Numbers

How can Internet speed be 10 times slower without a router than when using the same connection with a router?

Mug and wireframe entirely disappeared

Handling Null values (and equivalents) routinely in Python

How to deal with employer who keeps me at work after working hours

Install LibreOffice-Writer Only not LibreOffice whole package

Is there a word for food that's gone 'bad', but is still edible?

What is the closest airport to the center of the city it serves?

Correct way of drawing empty, half-filled and fully filled circles?

Are the Night's Watch still required?

Out of scope work duties and resignation

Why didn't this character get a funeral at the end of Avengers: Endgame?

Are there terms in German for different skull shapes?

Which sphere is fastest?

As a GM, is it bad form to ask for a moment to think when improvising?

Will 700 more planes a day fly because of the Heathrow expansion?



Positioning a resizable widget inside a scroll area


QGraphicsItem::setTransformOriginPoint bug when trying to scale imageHow does a Qt custom widget notify ScrollArea parent about change of viewresize problem in scroll areaQWidget is not showing up on entire screenUnwanted margin inside QGraphicsView with ScrollbarsNothing showing up in QScrollAreaScale a QGraphicsView without Scaling a QWidget that has been added to itHow to use QML Scale Element for incremental scaling with different originScaling a rotated item based on top left moves the itemMove QGraphicsView top left to a certain point in QGraphicsScene manually






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















I have a scroll area that contains a resizable widget. The user is able to increment and decrement the integer scale factor of this inner widget (which changes its size). When the user increments the scale, the part of the inner widget visible in the top left corner remains fixed. This gives the effect of zooming into the top left corner of the view.



When the size of the inner widget changes, I need to scroll the inner widget to make it look like the user is zooming into the center of the view. I want to keep the part of the widget in the center of the view fixed in the center while resizing.



I drew some diagrams to help visualise the problem. The pink rectangle is the inner widget. The brown rectangle is the view onto the widget through the scroll area. The green dots are fixed points on the inner widget.



Before scalingBefore scaling



After scaling (current undesirable behaviour)After scaling (current undesirable behaviour)



After scaling (desired behaviour)After scaling (desired behaviour)



As you can (hopefully) see from these crudely drawn diagrams. Simply increasing the size of a widget inside a scroll area results on zooming into the top left corner or the view. I have to do something more to zoom into the center of the view. Also, the inner widget can be much smaller than the scroll area. I only want to shift the inner widget when it is larger than the scroll area.



This is a minimal example of the undesirable behaviour. Pressing Z (after clicking on the inner widget to change focus) will zoom into the top left corner of the view. I want to zoom into the center of the view.



#include <QtGui/qpainter.h>
#include <QtWidgets/qscrollbar.h>
#include <QtWidgets/qscrollarea.h>
#include <QtWidgets/qmainwindow.h>
#include <QtWidgets/qapplication.h>

class InnerWidget final : public QWidget
public:
explicit InnerWidget(QScrollArea *parent)
: QWidgetparent, parentparent
updateSize();
setFocusPolicy(Qt::StrongFocus);


private:
QScrollArea *parent;
int scale = 1;

void updateSize()
setFixedSize(256 * scale, 256 * scale);


void paintEvent(QPaintEvent *) override
QPainter painterthis;
const QColor green = 0, 255, 0;
painter.fillRect(0, 0, width(), height(), 255, 255, 255);
painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


void keyPressEvent(QKeyEvent *event) override
if (event->isAutoRepeat()) return;
QScrollBar *hbar = parent->horizontalScrollBar();
QScrollBar *vbar = parent->verticalScrollBar();
if (event->key() == Qt::Key_Z)
// need to call bar->setValue and bar->value here
scale = std::min(scale + 1, 64);
updateSize();
else if (event->key() == Qt::Key_X)
// here too
scale = std::max(scale - 1, 1);
updateSize();


;

int main(int argc, char **argv)
QApplication appargc, argv;
QMainWindow window;
QScrollArea scrollArea&window;
InnerWidget inner&scrollArea;
window.setBaseSize(512, 512);
window.setCentralWidget(&scrollArea);
scrollArea.setAlignment(Qt::AlignCenter);
scrollArea.setWidget(&inner);
window.show();
return app.exec();



To reproduce the problem, zoom in a couple of times then position one of the rectangles in the center of the window. Zooming will move the rectangle toward the bottom right corner. I want zooming to keep the rectangle in the center.



This feels like an easy problem but I can’t seem to get my head around the math. I’ve tried various calculations on the scroll values but none of them seem to behave as I want.










share|improve this question






























    1















    I have a scroll area that contains a resizable widget. The user is able to increment and decrement the integer scale factor of this inner widget (which changes its size). When the user increments the scale, the part of the inner widget visible in the top left corner remains fixed. This gives the effect of zooming into the top left corner of the view.



    When the size of the inner widget changes, I need to scroll the inner widget to make it look like the user is zooming into the center of the view. I want to keep the part of the widget in the center of the view fixed in the center while resizing.



    I drew some diagrams to help visualise the problem. The pink rectangle is the inner widget. The brown rectangle is the view onto the widget through the scroll area. The green dots are fixed points on the inner widget.



    Before scalingBefore scaling



    After scaling (current undesirable behaviour)After scaling (current undesirable behaviour)



    After scaling (desired behaviour)After scaling (desired behaviour)



    As you can (hopefully) see from these crudely drawn diagrams. Simply increasing the size of a widget inside a scroll area results on zooming into the top left corner or the view. I have to do something more to zoom into the center of the view. Also, the inner widget can be much smaller than the scroll area. I only want to shift the inner widget when it is larger than the scroll area.



    This is a minimal example of the undesirable behaviour. Pressing Z (after clicking on the inner widget to change focus) will zoom into the top left corner of the view. I want to zoom into the center of the view.



    #include <QtGui/qpainter.h>
    #include <QtWidgets/qscrollbar.h>
    #include <QtWidgets/qscrollarea.h>
    #include <QtWidgets/qmainwindow.h>
    #include <QtWidgets/qapplication.h>

    class InnerWidget final : public QWidget
    public:
    explicit InnerWidget(QScrollArea *parent)
    : QWidgetparent, parentparent
    updateSize();
    setFocusPolicy(Qt::StrongFocus);


    private:
    QScrollArea *parent;
    int scale = 1;

    void updateSize()
    setFixedSize(256 * scale, 256 * scale);


    void paintEvent(QPaintEvent *) override
    QPainter painterthis;
    const QColor green = 0, 255, 0;
    painter.fillRect(0, 0, width(), height(), 255, 255, 255);
    painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
    painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


    void keyPressEvent(QKeyEvent *event) override
    if (event->isAutoRepeat()) return;
    QScrollBar *hbar = parent->horizontalScrollBar();
    QScrollBar *vbar = parent->verticalScrollBar();
    if (event->key() == Qt::Key_Z)
    // need to call bar->setValue and bar->value here
    scale = std::min(scale + 1, 64);
    updateSize();
    else if (event->key() == Qt::Key_X)
    // here too
    scale = std::max(scale - 1, 1);
    updateSize();


    ;

    int main(int argc, char **argv)
    QApplication appargc, argv;
    QMainWindow window;
    QScrollArea scrollArea&window;
    InnerWidget inner&scrollArea;
    window.setBaseSize(512, 512);
    window.setCentralWidget(&scrollArea);
    scrollArea.setAlignment(Qt::AlignCenter);
    scrollArea.setWidget(&inner);
    window.show();
    return app.exec();



    To reproduce the problem, zoom in a couple of times then position one of the rectangles in the center of the window. Zooming will move the rectangle toward the bottom right corner. I want zooming to keep the rectangle in the center.



    This feels like an easy problem but I can’t seem to get my head around the math. I’ve tried various calculations on the scroll values but none of them seem to behave as I want.










    share|improve this question


























      1












      1








      1








      I have a scroll area that contains a resizable widget. The user is able to increment and decrement the integer scale factor of this inner widget (which changes its size). When the user increments the scale, the part of the inner widget visible in the top left corner remains fixed. This gives the effect of zooming into the top left corner of the view.



      When the size of the inner widget changes, I need to scroll the inner widget to make it look like the user is zooming into the center of the view. I want to keep the part of the widget in the center of the view fixed in the center while resizing.



      I drew some diagrams to help visualise the problem. The pink rectangle is the inner widget. The brown rectangle is the view onto the widget through the scroll area. The green dots are fixed points on the inner widget.



      Before scalingBefore scaling



      After scaling (current undesirable behaviour)After scaling (current undesirable behaviour)



      After scaling (desired behaviour)After scaling (desired behaviour)



      As you can (hopefully) see from these crudely drawn diagrams. Simply increasing the size of a widget inside a scroll area results on zooming into the top left corner or the view. I have to do something more to zoom into the center of the view. Also, the inner widget can be much smaller than the scroll area. I only want to shift the inner widget when it is larger than the scroll area.



      This is a minimal example of the undesirable behaviour. Pressing Z (after clicking on the inner widget to change focus) will zoom into the top left corner of the view. I want to zoom into the center of the view.



      #include <QtGui/qpainter.h>
      #include <QtWidgets/qscrollbar.h>
      #include <QtWidgets/qscrollarea.h>
      #include <QtWidgets/qmainwindow.h>
      #include <QtWidgets/qapplication.h>

      class InnerWidget final : public QWidget
      public:
      explicit InnerWidget(QScrollArea *parent)
      : QWidgetparent, parentparent
      updateSize();
      setFocusPolicy(Qt::StrongFocus);


      private:
      QScrollArea *parent;
      int scale = 1;

      void updateSize()
      setFixedSize(256 * scale, 256 * scale);


      void paintEvent(QPaintEvent *) override
      QPainter painterthis;
      const QColor green = 0, 255, 0;
      painter.fillRect(0, 0, width(), height(), 255, 255, 255);
      painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
      painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


      void keyPressEvent(QKeyEvent *event) override
      if (event->isAutoRepeat()) return;
      QScrollBar *hbar = parent->horizontalScrollBar();
      QScrollBar *vbar = parent->verticalScrollBar();
      if (event->key() == Qt::Key_Z)
      // need to call bar->setValue and bar->value here
      scale = std::min(scale + 1, 64);
      updateSize();
      else if (event->key() == Qt::Key_X)
      // here too
      scale = std::max(scale - 1, 1);
      updateSize();


      ;

      int main(int argc, char **argv)
      QApplication appargc, argv;
      QMainWindow window;
      QScrollArea scrollArea&window;
      InnerWidget inner&scrollArea;
      window.setBaseSize(512, 512);
      window.setCentralWidget(&scrollArea);
      scrollArea.setAlignment(Qt::AlignCenter);
      scrollArea.setWidget(&inner);
      window.show();
      return app.exec();



      To reproduce the problem, zoom in a couple of times then position one of the rectangles in the center of the window. Zooming will move the rectangle toward the bottom right corner. I want zooming to keep the rectangle in the center.



      This feels like an easy problem but I can’t seem to get my head around the math. I’ve tried various calculations on the scroll values but none of them seem to behave as I want.










      share|improve this question
















      I have a scroll area that contains a resizable widget. The user is able to increment and decrement the integer scale factor of this inner widget (which changes its size). When the user increments the scale, the part of the inner widget visible in the top left corner remains fixed. This gives the effect of zooming into the top left corner of the view.



      When the size of the inner widget changes, I need to scroll the inner widget to make it look like the user is zooming into the center of the view. I want to keep the part of the widget in the center of the view fixed in the center while resizing.



      I drew some diagrams to help visualise the problem. The pink rectangle is the inner widget. The brown rectangle is the view onto the widget through the scroll area. The green dots are fixed points on the inner widget.



      Before scalingBefore scaling



      After scaling (current undesirable behaviour)After scaling (current undesirable behaviour)



      After scaling (desired behaviour)After scaling (desired behaviour)



      As you can (hopefully) see from these crudely drawn diagrams. Simply increasing the size of a widget inside a scroll area results on zooming into the top left corner or the view. I have to do something more to zoom into the center of the view. Also, the inner widget can be much smaller than the scroll area. I only want to shift the inner widget when it is larger than the scroll area.



      This is a minimal example of the undesirable behaviour. Pressing Z (after clicking on the inner widget to change focus) will zoom into the top left corner of the view. I want to zoom into the center of the view.



      #include <QtGui/qpainter.h>
      #include <QtWidgets/qscrollbar.h>
      #include <QtWidgets/qscrollarea.h>
      #include <QtWidgets/qmainwindow.h>
      #include <QtWidgets/qapplication.h>

      class InnerWidget final : public QWidget
      public:
      explicit InnerWidget(QScrollArea *parent)
      : QWidgetparent, parentparent
      updateSize();
      setFocusPolicy(Qt::StrongFocus);


      private:
      QScrollArea *parent;
      int scale = 1;

      void updateSize()
      setFixedSize(256 * scale, 256 * scale);


      void paintEvent(QPaintEvent *) override
      QPainter painterthis;
      const QColor green = 0, 255, 0;
      painter.fillRect(0, 0, width(), height(), 255, 255, 255);
      painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
      painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


      void keyPressEvent(QKeyEvent *event) override
      if (event->isAutoRepeat()) return;
      QScrollBar *hbar = parent->horizontalScrollBar();
      QScrollBar *vbar = parent->verticalScrollBar();
      if (event->key() == Qt::Key_Z)
      // need to call bar->setValue and bar->value here
      scale = std::min(scale + 1, 64);
      updateSize();
      else if (event->key() == Qt::Key_X)
      // here too
      scale = std::max(scale - 1, 1);
      updateSize();


      ;

      int main(int argc, char **argv)
      QApplication appargc, argv;
      QMainWindow window;
      QScrollArea scrollArea&window;
      InnerWidget inner&scrollArea;
      window.setBaseSize(512, 512);
      window.setCentralWidget(&scrollArea);
      scrollArea.setAlignment(Qt::AlignCenter);
      scrollArea.setWidget(&inner);
      window.show();
      return app.exec();



      To reproduce the problem, zoom in a couple of times then position one of the rectangles in the center of the window. Zooming will move the rectangle toward the bottom right corner. I want zooming to keep the rectangle in the center.



      This feels like an easy problem but I can’t seem to get my head around the math. I’ve tried various calculations on the scroll values but none of them seem to behave as I want.







      c++ qt qt5






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 23 at 3:27







      Kerndog73

















      asked Mar 22 at 23:30









      Kerndog73Kerndog73

      1,7161031




      1,7161031






















          1 Answer
          1






          active

          oldest

          votes


















          0














          I messed around with the numbers for a while and then I figured it out. Here’s the fully working solution.



          #include <QtGui/qpainter.h>
          #include <QtWidgets/qscrollbar.h>
          #include <QtWidgets/qmainwindow.h>
          #include <QtWidgets/qscrollarea.h>
          #include <QtWidgets/qapplication.h>

          class InnerWidget final : public QWidget
          public:
          explicit InnerWidget(QScrollArea *parent)
          : QWidgetparent, parentparent, scale1
          updateSize();
          setFocusPolicy(Qt::StrongFocus);


          private:
          QScrollArea *parent;
          int scale;

          void updateSize()
          setFixedSize(256 * scale, 256 * scale);


          void paintEvent(QPaintEvent *) override
          QPainter painterthis;
          const QColor green = 0, 255, 0;
          painter.fillRect(0, 0, width(), height(), 255, 255, 255);
          painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
          painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


          void adjustScroll(const int oldScale)
          if (scale == oldScale) return;
          QScrollBar *hbar = parent->horizontalScrollBar();
          QScrollBar *vbar = parent->verticalScrollBar();
          if (width() >= parent->width())
          const int halfWidth = parent->width() / 2;
          hbar->setValue((hbar->value() + halfWidth) * scale / oldScale - halfWidth);

          if (height() >= parent->height())
          const int halfHeight = parent->height() / 2;
          vbar->setValue((vbar->value() + halfHeight) * scale / oldScale - halfHeight);



          void keyPressEvent(QKeyEvent *event) override
          if (event->isAutoRepeat()) return;
          const int oldScale = scale;
          if (event->key() == Qt::Key_Z)
          scale = std::min(scale + 1, 64);
          updateSize();
          adjustScroll(oldScale);
          else if (event->key() == Qt::Key_X)
          scale = std::max(scale - 1, 1);
          updateSize();
          adjustScroll(oldScale);


          ;

          int main(int argc, char **argv)
          QApplication appargc, argv;
          QMainWindow window;
          QScrollArea scrollArea&window;
          InnerWidget inner&scrollArea;
          window.setBaseSize(512, 512);
          window.setCentralWidget(&scrollArea);
          scrollArea.setAlignment(Qt::AlignCenter);
          scrollArea.setWidget(&inner);
          window.show();
          return app.exec();






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55309055%2fpositioning-a-resizable-widget-inside-a-scroll-area%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0














            I messed around with the numbers for a while and then I figured it out. Here’s the fully working solution.



            #include <QtGui/qpainter.h>
            #include <QtWidgets/qscrollbar.h>
            #include <QtWidgets/qmainwindow.h>
            #include <QtWidgets/qscrollarea.h>
            #include <QtWidgets/qapplication.h>

            class InnerWidget final : public QWidget
            public:
            explicit InnerWidget(QScrollArea *parent)
            : QWidgetparent, parentparent, scale1
            updateSize();
            setFocusPolicy(Qt::StrongFocus);


            private:
            QScrollArea *parent;
            int scale;

            void updateSize()
            setFixedSize(256 * scale, 256 * scale);


            void paintEvent(QPaintEvent *) override
            QPainter painterthis;
            const QColor green = 0, 255, 0;
            painter.fillRect(0, 0, width(), height(), 255, 255, 255);
            painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
            painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


            void adjustScroll(const int oldScale)
            if (scale == oldScale) return;
            QScrollBar *hbar = parent->horizontalScrollBar();
            QScrollBar *vbar = parent->verticalScrollBar();
            if (width() >= parent->width())
            const int halfWidth = parent->width() / 2;
            hbar->setValue((hbar->value() + halfWidth) * scale / oldScale - halfWidth);

            if (height() >= parent->height())
            const int halfHeight = parent->height() / 2;
            vbar->setValue((vbar->value() + halfHeight) * scale / oldScale - halfHeight);



            void keyPressEvent(QKeyEvent *event) override
            if (event->isAutoRepeat()) return;
            const int oldScale = scale;
            if (event->key() == Qt::Key_Z)
            scale = std::min(scale + 1, 64);
            updateSize();
            adjustScroll(oldScale);
            else if (event->key() == Qt::Key_X)
            scale = std::max(scale - 1, 1);
            updateSize();
            adjustScroll(oldScale);


            ;

            int main(int argc, char **argv)
            QApplication appargc, argv;
            QMainWindow window;
            QScrollArea scrollArea&window;
            InnerWidget inner&scrollArea;
            window.setBaseSize(512, 512);
            window.setCentralWidget(&scrollArea);
            scrollArea.setAlignment(Qt::AlignCenter);
            scrollArea.setWidget(&inner);
            window.show();
            return app.exec();






            share|improve this answer





























              0














              I messed around with the numbers for a while and then I figured it out. Here’s the fully working solution.



              #include <QtGui/qpainter.h>
              #include <QtWidgets/qscrollbar.h>
              #include <QtWidgets/qmainwindow.h>
              #include <QtWidgets/qscrollarea.h>
              #include <QtWidgets/qapplication.h>

              class InnerWidget final : public QWidget
              public:
              explicit InnerWidget(QScrollArea *parent)
              : QWidgetparent, parentparent, scale1
              updateSize();
              setFocusPolicy(Qt::StrongFocus);


              private:
              QScrollArea *parent;
              int scale;

              void updateSize()
              setFixedSize(256 * scale, 256 * scale);


              void paintEvent(QPaintEvent *) override
              QPainter painterthis;
              const QColor green = 0, 255, 0;
              painter.fillRect(0, 0, width(), height(), 255, 255, 255);
              painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
              painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


              void adjustScroll(const int oldScale)
              if (scale == oldScale) return;
              QScrollBar *hbar = parent->horizontalScrollBar();
              QScrollBar *vbar = parent->verticalScrollBar();
              if (width() >= parent->width())
              const int halfWidth = parent->width() / 2;
              hbar->setValue((hbar->value() + halfWidth) * scale / oldScale - halfWidth);

              if (height() >= parent->height())
              const int halfHeight = parent->height() / 2;
              vbar->setValue((vbar->value() + halfHeight) * scale / oldScale - halfHeight);



              void keyPressEvent(QKeyEvent *event) override
              if (event->isAutoRepeat()) return;
              const int oldScale = scale;
              if (event->key() == Qt::Key_Z)
              scale = std::min(scale + 1, 64);
              updateSize();
              adjustScroll(oldScale);
              else if (event->key() == Qt::Key_X)
              scale = std::max(scale - 1, 1);
              updateSize();
              adjustScroll(oldScale);


              ;

              int main(int argc, char **argv)
              QApplication appargc, argv;
              QMainWindow window;
              QScrollArea scrollArea&window;
              InnerWidget inner&scrollArea;
              window.setBaseSize(512, 512);
              window.setCentralWidget(&scrollArea);
              scrollArea.setAlignment(Qt::AlignCenter);
              scrollArea.setWidget(&inner);
              window.show();
              return app.exec();






              share|improve this answer



























                0












                0








                0







                I messed around with the numbers for a while and then I figured it out. Here’s the fully working solution.



                #include <QtGui/qpainter.h>
                #include <QtWidgets/qscrollbar.h>
                #include <QtWidgets/qmainwindow.h>
                #include <QtWidgets/qscrollarea.h>
                #include <QtWidgets/qapplication.h>

                class InnerWidget final : public QWidget
                public:
                explicit InnerWidget(QScrollArea *parent)
                : QWidgetparent, parentparent, scale1
                updateSize();
                setFocusPolicy(Qt::StrongFocus);


                private:
                QScrollArea *parent;
                int scale;

                void updateSize()
                setFixedSize(256 * scale, 256 * scale);


                void paintEvent(QPaintEvent *) override
                QPainter painterthis;
                const QColor green = 0, 255, 0;
                painter.fillRect(0, 0, width(), height(), 255, 255, 255);
                painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
                painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


                void adjustScroll(const int oldScale)
                if (scale == oldScale) return;
                QScrollBar *hbar = parent->horizontalScrollBar();
                QScrollBar *vbar = parent->verticalScrollBar();
                if (width() >= parent->width())
                const int halfWidth = parent->width() / 2;
                hbar->setValue((hbar->value() + halfWidth) * scale / oldScale - halfWidth);

                if (height() >= parent->height())
                const int halfHeight = parent->height() / 2;
                vbar->setValue((vbar->value() + halfHeight) * scale / oldScale - halfHeight);



                void keyPressEvent(QKeyEvent *event) override
                if (event->isAutoRepeat()) return;
                const int oldScale = scale;
                if (event->key() == Qt::Key_Z)
                scale = std::min(scale + 1, 64);
                updateSize();
                adjustScroll(oldScale);
                else if (event->key() == Qt::Key_X)
                scale = std::max(scale - 1, 1);
                updateSize();
                adjustScroll(oldScale);


                ;

                int main(int argc, char **argv)
                QApplication appargc, argv;
                QMainWindow window;
                QScrollArea scrollArea&window;
                InnerWidget inner&scrollArea;
                window.setBaseSize(512, 512);
                window.setCentralWidget(&scrollArea);
                scrollArea.setAlignment(Qt::AlignCenter);
                scrollArea.setWidget(&inner);
                window.show();
                return app.exec();






                share|improve this answer















                I messed around with the numbers for a while and then I figured it out. Here’s the fully working solution.



                #include <QtGui/qpainter.h>
                #include <QtWidgets/qscrollbar.h>
                #include <QtWidgets/qmainwindow.h>
                #include <QtWidgets/qscrollarea.h>
                #include <QtWidgets/qapplication.h>

                class InnerWidget final : public QWidget
                public:
                explicit InnerWidget(QScrollArea *parent)
                : QWidgetparent, parentparent, scale1
                updateSize();
                setFocusPolicy(Qt::StrongFocus);


                private:
                QScrollArea *parent;
                int scale;

                void updateSize()
                setFixedSize(256 * scale, 256 * scale);


                void paintEvent(QPaintEvent *) override
                QPainter painterthis;
                const QColor green = 0, 255, 0;
                painter.fillRect(0, 0, width(), height(), 255, 255, 255);
                painter.fillRect(32 * scale, 32 * scale, 16 * scale, 16 * scale, green);
                painter.fillRect(128 * scale, 128 * scale, 16 * scale, 16 * scale, green);


                void adjustScroll(const int oldScale)
                if (scale == oldScale) return;
                QScrollBar *hbar = parent->horizontalScrollBar();
                QScrollBar *vbar = parent->verticalScrollBar();
                if (width() >= parent->width())
                const int halfWidth = parent->width() / 2;
                hbar->setValue((hbar->value() + halfWidth) * scale / oldScale - halfWidth);

                if (height() >= parent->height())
                const int halfHeight = parent->height() / 2;
                vbar->setValue((vbar->value() + halfHeight) * scale / oldScale - halfHeight);



                void keyPressEvent(QKeyEvent *event) override
                if (event->isAutoRepeat()) return;
                const int oldScale = scale;
                if (event->key() == Qt::Key_Z)
                scale = std::min(scale + 1, 64);
                updateSize();
                adjustScroll(oldScale);
                else if (event->key() == Qt::Key_X)
                scale = std::max(scale - 1, 1);
                updateSize();
                adjustScroll(oldScale);


                ;

                int main(int argc, char **argv)
                QApplication appargc, argv;
                QMainWindow window;
                QScrollArea scrollArea&window;
                InnerWidget inner&scrollArea;
                window.setBaseSize(512, 512);
                window.setCentralWidget(&scrollArea);
                scrollArea.setAlignment(Qt::AlignCenter);
                scrollArea.setWidget(&inner);
                window.show();
                return app.exec();







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Mar 23 at 5:04

























                answered Mar 23 at 4:42









                Kerndog73Kerndog73

                1,7161031




                1,7161031





























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55309055%2fpositioning-a-resizable-widget-inside-a-scroll-area%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                    Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript