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

相关推荐
人工智能教学实践1 小时前
基于 YOLOv8+PyQt5 界面自适应的无人机红外目标检测系统项目介绍框架
qt·yolo·无人机
誰能久伴不乏1 小时前
从零开始:用Qt开发一个功能强大的文本编辑器——WPS项目全解析
数据库·qt·wps
m0_699659568 小时前
QT知识点复习
开发语言·qt
深蓝海拓10 小时前
基于深度学习的视觉检测小项目(十六) 用户管理界面的组态
人工智能·python·深度学习·qt·pyqt
弄不死的强仔13 小时前
可被electron等调用的Qt截图-录屏工具【源码开放】
前端·javascript·qt·electron·贴图·qt5
行十万里人生1 天前
Qt事件处理:理解处理器、过滤器与事件系统
开发语言·git·qt·华为od·华为·华为云·harmonyos
黑金IT1 天前
Python3 + Qt5:实现AJAX异步更新UI
qt·ui·ajax
人工智能教学实践1 天前
基于 yolov8_pyqt5 自适应界面设计的火灾检测系统 demo:毕业设计参考
qt·yolo·课程设计
扎量丙不要犟1 天前
跨平台的客户端gui到底是选“原生”还是web
前端·javascript·c++·qt·rust·electron·tauri
笑鸿的学习笔记2 天前
qt-Quick3D笔记之官方例程Runtimeloader Example运行笔记
笔记·qt·3d