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;
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 scaling
After scaling (current undesirable 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
add a comment |
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 scaling
After scaling (current undesirable 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
add a comment |
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 scaling
After scaling (current undesirable 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
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 scaling
After scaling (current undesirable 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
c++ qt qt5
edited Mar 23 at 3:27
Kerndog73
asked Mar 22 at 23:30
Kerndog73Kerndog73
1,7161031
1,7161031
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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();
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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();
add a comment |
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();
add a comment |
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();
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();
edited Mar 23 at 5:04
answered Mar 23 at 4:42
Kerndog73Kerndog73
1,7161031
1,7161031
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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