如何滚动自定义 QGraphicsWidget 的所有内容?
How do I scroll all the contents of my custom QGraphicsWidgets?
我有一个名为 "TestContentArea" 的自定义 QGraphicsWidget,它已添加到 QGraphicsScene。在我的自定义 QGraphicsWidget 中,我添加了一些添加到其布局中的子 QGraphicsWidgets。我遇到的问题是自定义 QGraphicsWidget 的内容超出了用户可以滚动的区域。下面附上了一个最小的例子来说明这一点。 100 个矩形中只有 11 个是可见的。如何滚动此示例中的所有 100 个子窗口小部件?
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());
}
问题是因为你定义的 sceneRect
与它应该的相比非常小,那就是 QScrollBar
参考 SceneRect
来建立它的范围。所以解决方法很简单,不设置任何sceneRect
让Qt自己计算,因为它改变了:
m_scene = new QGraphicsScene(0, 0, 880, 630, this);
至:
m_scene = new QGraphicsScene(this);
我有一个名为 "TestContentArea" 的自定义 QGraphicsWidget,它已添加到 QGraphicsScene。在我的自定义 QGraphicsWidget 中,我添加了一些添加到其布局中的子 QGraphicsWidgets。我遇到的问题是自定义 QGraphicsWidget 的内容超出了用户可以滚动的区域。下面附上了一个最小的例子来说明这一点。 100 个矩形中只有 11 个是可见的。如何滚动此示例中的所有 100 个子窗口小部件?
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());
}
问题是因为你定义的 sceneRect
与它应该的相比非常小,那就是 QScrollBar
参考 SceneRect
来建立它的范围。所以解决方法很简单,不设置任何sceneRect
让Qt自己计算,因为它改变了:
m_scene = new QGraphicsScene(0, 0, 880, 630, this);
至:
m_scene = new QGraphicsScene(this);