QGraphicsView实现拖拽缩放_qt qgraphicview 视图缩放-CSDN博客
首先创建视图框架,分别是QGraphicsView、QGraphicsScene和QGraphicsItem。
其中QGraphicsItem需要继承重写,重写的派生类中必须需要实现两个函数,paint(item的绘制函数)和boundingRect(item的大小位置函数),因为这两个是纯虚函数。
然后在view视图中添加Scene。设置view的
setDragMode打开拖拽功能。设置view的setTransform实现缩放功能。
示例代码如下,该示例支持按钮缩放,滚轮缩放和鼠标拖拽。
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mgraaphicsview.h"
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private:
MGraaphicsView* m_view = nullptr;
};
#endif // WIDGET_H
cpp
#include "widget.h"
#include <QPushButton>
#include <QGridLayout>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent)
{
QPushButton* bbtn = new QPushButton("放大",this);
QPushButton* sbtn = new QPushButton("缩小",this);
QPushButton* obtn = new QPushButton("还原",this);
QGraphicsScene* scene = new QGraphicsScene();
m_view = new MGraaphicsView(scene);
QGridLayout* lay = new QGridLayout(this);
lay->addWidget(m_view,0,0,10,10);
lay->addWidget(bbtn,10,0,1,1);
lay->addWidget(sbtn,10,1,1,1);
lay->addWidget(obtn,10,2,1,1);
lay->setMargin(0);
this->setLayout(lay);
connect(bbtn,&QPushButton::clicked,this,[=]()
{
m_view->zoomOnce(1);
});
connect(sbtn,&QPushButton::clicked,this,[=]()
{
m_view->zoomOnce(-1);
});
connect(obtn,&QPushButton::clicked,this,[=]()
{
});
}
Widget::~Widget()
{
}
view视图框架类,相当于显示窗口,给它添加QGraphicsScene,使其拥有界面,且可以添加多个QGraphicsScene。
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);和
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);隐藏滚动条。
cpp
#ifndef MGRAAPHICSVIEW_H
#define MGRAAPHICSVIEW_H
#include <QGraphicsView>
#include <QWheelEvent>
#include "mgraphicsitem.h"
class MGraaphicsView : public QGraphicsView
{
public:
MGraaphicsView(QGraphicsScene *scene, QWidget *parent = nullptr);
void wheelEvent(QWheelEvent *event);
void zoomOnce(int val);
int m_minZoom;
int m_maxZoom;
int m_zoom = 0;
double m_zoomnum = 1;
MGraphicsItem* _item = nullptr;
};
#endif // MGRAAPHICSVIEW_H
cpp
#include "mgraaphicsview.h"
#include <qmath.h>
#include <QDebug>
MGraaphicsView::MGraaphicsView(QGraphicsScene *scene, QWidget *parent)
:QGraphicsView(scene,parent)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);
setDragMode(QGraphicsView::ScrollHandDrag);
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
_item = new MGraphicsItem();
_item->setboundingRect(0,0,1000,1000);
scene->addItem(_item);
}
void MGraaphicsView::wheelEvent(QWheelEvent *event)
{
event->accept();
zoomOnce(event->delta());
}
void MGraaphicsView::zoomOnce(int val)
{
if (val > 0)
{
m_zoom++;
auto scaleValue = qPow(2, m_zoom);
setTransform(QTransform::fromScale(scaleValue, scaleValue));
}
else
{
m_zoom--;
auto scaleValue = qPow(2, m_zoom);
setTransform(QTransform::fromScale(scaleValue, scaleValue));
}
}
QGraphicsItem类,它是界面上的控件,相对于Qt的标准控件,它更省内存。且在中QGraphicsScene中也可以添加QT标准控件。通过addWidget即可。如下
cpp
QWidget *w = new QWidget ()
QGraphicsProxyWidget* pwidget = m_mapView->scene()->addWidget(w);
pwidget->setFlag(QGraphicsItem::ItemIgnoresTransformations, true); //禁止随界面缩放而缩放
pwidget->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); //禁止随界面大小变化而变化
继承QGraphicsItem实现的自定义Item,由于QGraphicsItem它不继承QObject,所有它不具备信号槽机制,如果想要实现信号槽,可以多重继承,既继承QObject,又继承QGraphicsItem,就像QGraphicsObject它一样。
cpp
#ifndef MGRAPHICSITEM_H
#define MGRAPHICSITEM_H
#include <QGraphicsItem>
#include <QPainter>
#include <QSvgRenderer>
class MGraphicsItem : public QGraphicsItem
{
public:
MGraphicsItem();
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);
virtual QRectF boundingRect() const ;
void setboundingRect(int x, int y, int w, int h);
int m_x = 0;
int m_y = 0;
int m_w = 0;
int m_h = 0;
QSvgRenderer* _renderer = nullptr;
void reLoad(QString name);
};
#endif // MGRAPHICSITEM_H
cpp
#include "mgraphicsitem.h"
MGraphicsItem::MGraphicsItem()
{
_renderer = new QSvgRenderer;
_renderer->load(QString("test.svg"));
}
void MGraphicsItem::reLoad(QString name)
{
_renderer->load(name);
}
void MGraphicsItem::setboundingRect(int x,int y,int w,int h)
{
m_x = x;
m_y = y;
m_w = w;
m_h = h;
}
void MGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
if (!_renderer->isValid())
return;
_renderer->render(painter, boundingRect());
}
QRectF MGraphicsItem::boundingRect() const
{
return QRectF(m_x,m_y,m_w,m_h);
}
QSvgRenderer它是用来显示svg矢量图的一个代理类。