QGraphicsView实现拖拽缩放

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矢量图的一个代理类。

相关推荐
扶尔魔ocy6 小时前
【转载】QT使用linuxdeployqt打包
开发语言·qt
YxVoyager10 小时前
在VS2017中使用Qt的foreach宏,IntelliSense无法正确识别函数定义
c++·qt
轩情吖11 小时前
Qt的事件
开发语言·qt·事件·qt事件·qkeyevent·qmoveevent
小老鼠不吃猫12 小时前
Qt C++稳定职业规划
开发语言·c++·qt
轩情吖13 小时前
Qt的文件
开发语言·c++·qt·文件·qfileinfo·桌面级开发·qt文件操作
一晌小贪欢13 小时前
PyQt5 实战:批量图片添加水印工具(带右侧实时预览)(附代码及下载链接)
开发语言·qt·添加水印·图片添加水印·蹄片水印
小老鼠不吃猫1 天前
深入浅出(十三)QWT库——高稳定二维绘图
c++·qt·二维图
「QT(C++)开发工程师」2 天前
【Qt Creator 15.0.1 安装指南】
开发语言·qt
Max_uuc2 天前
【架构心法】炸毁巨石阵:从单体巨兽到微内核 (Microkernel) 插件化架构的 Qt C++ 工业软件演进
c++·qt·架构
「QT(C++)开发工程师」2 天前
# [特殊字符] Day 1:Qt 信号槽原理深入 - 核心学习笔记
c++·qt