I have a custom QGraphicsWidget called "TestContentArea" which is added to a QGraphicsScene. In my custom QGraphicsWidget, I am adding a number of children QGraphicsWidgets added to its layout. The problem I have is the contents of custom QGraphicsWidget extends beyond the area the user can scroll. Attached below is a minimum example that shows this. Only 11 rectangles are visible out of a 100. How can I scroll all 100 children widgets in this example?
MainWindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include "TestContentArea.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
//Constructor
explicit MainWindow(QWidget *parent = nullptr);
//Deconstructor
~MainWindow();
private:
//Private members
Ui::MainWindow *ui;
QGraphicsScene * m_scene;
QGraphicsView * m_view;
TestContentArea * m_testContentArea;
};
#endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_scene = new QGraphicsScene(0, 0, 880, 630, this);
m_view = new QGraphicsView(m_scene, this);
m_view->setAlignment(Qt::AlignLeft | Qt::AlignTop);
m_testContentArea = new TestContentArea();
m_scene->addItem(m_testContentArea);
setCentralWidget(m_view);
}
MainWindow::~MainWindow()
{
delete ui;
}
TestContentArea.h:
#ifndef TESTCONTENTAREA_H
#define TESTCONTENTAREA_H
#include <QGraphicsWidget>
#include <QGraphicsLinearLayout>
class TestContentArea: public QGraphicsWidget
{
public:
//Constructor
TestContentArea(QGraphicsWidget* parent = nullptr);
private:
//Private members
QGraphicsLinearLayout * m_layout;
};
#endif // TESTCONTENTAREA_H
TestContentArea.cpp:
#include "TestContentArea.h"
#include <QGraphicsLinearLayout>
#include <QGraphicsRectItem>
#include "RectangleWidget.h"
TestContentArea::TestContentArea(QGraphicsWidget* parent)
{
Q_UNUSED(parent);
setAcceptHoverEvents(true);
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
m_layout->setContentsMargins(30, 30, 0, 0);
for(int i= 0; i< 100; i++)
{
RectangleWidget* rect = new RectangleWidget(this);
m_layout->addItem(rect);
}
setLayout(m_layout);
}
RectangleWidget.h:
#ifndef Rectangle_H
#define Rectangle_H
#include <QGraphicsWidget>
#include <QJsonObject>
#include <QGraphicsLinearLayout>
#include <QGraphicsProxyWidget>
#include <QPushButton>
class RectangleWidget: public QGraphicsWidget
{
public:
RectangleWidget(QGraphicsWidget* parent = nullptr);
// Overriding functions
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
private:
//Private member variables
QGraphicsLinearLayout * m_layout;
QPushButton * m_button;
};
#endif // Rectangle_H
RectangleWidget.cpp:
#include "RectangleWidget.h"
#include <QPainter>
RectangleWidget::RectangleWidget(QGraphicsWidget *parent)
{
}
void RectangleWidget::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget /*= 0*/)
{
Q_UNUSED(widget);
Q_UNUSED(option);
//Draw border
painter->drawRoundedRect(boundingRect(), 0.0, 0.0);
}
QRectF RectangleWidget::boundingRect() const
{
return QRectF(QPointF(0,0), geometry().size());
}
The problem is caused because you are defining a very small sceneRect
compared to what it should be, and that is that the QScrollBar
take as references the SceneRect
to establish its range. So the solution is simple, do not set any sceneRect
so that Qt calculates it by itself, for it changes:
m_scene = new QGraphicsScene(0, 0, 880, 630, this);
to:
m_scene = new QGraphicsScene(this);