QScrollArea does not honor contentMargins setting
The QScrollArea ignores the parameter for some reason contentMargins
when I set the QGraphicsView as a widget. Looking at the snippet below, can anyone please tell me if I am doing something wrong or it could be a bug in the SDK?
Snippet 1 (works fine):
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);
QWidget *widgetToScroll = new QWidget(sa);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);
appWindow->show();
Snippet 2 (It's like the setContentMargins () call is completely ignored):
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(appWindow);
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentMargins(50, 50, 50, 50);
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);
widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(sa);
appWindow->setLayout(appWindowLayout);
appWindow->show();
Thank.
source to share
It looks like you are confusing the structure of how to nest QGraphicsView and QGraphicsScene. (Maybe it was just a typo?)
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(sa), sa);
should be changed to
QGraphicsView *widgetToScroll = new QGraphicsView(new QGraphicsScene(), sa);
or
QGraphicsView *widgetToScroll = new QGraphicsView();
sa->setWidget(widgetToScroll);
When you add a QWidget to a layout, you change the parent of the widget. When you set a widget (or QGraphicsView) to a QScrollArea, you change the parent of that widget. See Object Trees and Ownership for more information . Therefore, if you want to customize the QGraphicsView inside the QScrollArea, your code will look like this:
QWidget *appWindow = new QWidget;
QScrollArea *sa = new QScrollArea(); // No need to specify a parent here if
// you add it to a layout later
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
sa->setContentsMargins(50, 50, 50, 50);
QGraphicsView *widgetToScroll = new QGraphicsView();
widgetToScroll->setAlignment(Qt::AlignLeft | Qt::AlignTop);
widgetToScroll->resize(5000, 5000);
sa->setWidget(widgetToScroll); // This sets the parent for widgetToScroll
QVBoxLayout *appWindowLayout = new QVBoxLayout();
appWindowLayout->addWidget(sa); // This sets the parent for sa
appWindow->setLayout(appWindowLayout); // This sets the parent for appWindowLayout
appWindow->show();
As a side note ...
When using QGraphicsViews with QGraphicsScene, instead of setting margins with QScrollArea setContentsMargins, I use QGraphicsView's auto-scrolling and just set the rectangle scene to be larger, the size of my content as such:
QWidget *appWindow = new QWidget;
QGraphicsView *widgetToScroll = new QGraphicsView();
QGraphicsScene *scene = new QGraphicsScene();
scene->addRect(0,0, 5000, 5000);
widgetToScroll->setSceneRect(-50,-50, 5050, 5050);
widgetToScroll->setScene(scene);
QVBoxLayout *appWindowLayout = new QVBoxLayout(appWindow);
appWindowLayout->addWidget(widgetToScroll);
appWindow->setLayout(appWindowLayout);
appWindow->show();
QGraphicsView includes quite a bit more than just auto scrolling when needed. You can resize everything inside and a little more. This is great for 2D layouts, interactions, and animations. For more information, see the "Qt Graphical View Framework" at http://doc.qt.io/qt-5/graphicsview.html .
Here is some more detailed information that can be helpful when using margins and paddings: The Box model used by QStyleSheets.
source to share
To ensure the correct use of the content fields for the QScrollArea widget, I will subclass it and manually set the view fields (which is a protected method in QT 4.7).
// Extended class
class QScrollAreaWithMargins : public QScrollArea
{
public:
virtual void resizeEvent(QResizeEvent *event) override
{
// Define content margins here
setViewportMargins(5, 0, 0, 0); // <<<<< SET MARGINS HERE
QScrollArea::resizeEvent(event);
}
};
// Usage
//...
mEditorScrollArea = new QScrollAreaWithMargins();
//...
source to share