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

相关推荐
优雅的小武先生25 分钟前
QT中的按钮控件和comboBox控件和spinBox控件无法点击的bug
开发语言·qt·bug
Death20026 分钟前
使用Qt进行TCP和UDP网络编程
网络·c++·qt·tcp/ip
海绵波波1072 小时前
Qt操作主/从视图及XML——实例:汽车管理系统
xml·qt·汽车
Fairy_sevenseven2 小时前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
Death2002 小时前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
niu_sama3 小时前
基于muduo库函数实现protobuf协议的通信
开发语言·qt
不写八个3 小时前
Qt教程(001):Qt概述与安装
开发语言·qt
Death2003 小时前
Qt 3D、QtQuick、QtQuick 3D 和 QML 的关系
c语言·c++·qt·3d·c#
一律清风13 小时前
QT-文件创建时间修改器
c++·qt
不知所云,13 小时前
qt cmake自定义资源目录,手动加载资源(图片, qss文件)
开发语言·qt