• QGraphicsView实现拖拽缩放


    20221104_094101

    首先创建视图框架,分别是QGraphicsView、QGraphicsScene和QGraphicsItem。
    其中QGraphicsItem需要继承重写,重写的派生类中必须需要实现两个函数,paint(item的绘制函数)和boundingRect(item的大小位置函数),因为这两个是纯虚函数。

    然后在view视图中添加Scene。设置view的
    setDragMode打开拖拽功能。设置view的setTransform实现缩放功能。

    示例代码如下,该示例支持按钮缩放,滚轮缩放和鼠标拖拽。

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include 
    #include "mgraaphicsview.h"
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private:
        MGraaphicsView* m_view = nullptr;
    };
    
    #endif // WIDGET_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    #include "widget.h"
    
    #include 
    #include 
    #include 
    
    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()
    {
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    view视图框架类,相当于显示窗口,给它添加QGraphicsScene,使其拥有界面,且可以添加多个QGraphicsScene。
    setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);和
    setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOff);隐藏滚动条。

    #ifndef MGRAAPHICSVIEW_H
    #define MGRAAPHICSVIEW_H
    
    #include 
    #include 
    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    #include "mgraaphicsview.h"
    #include 
    #include 
    
    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));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    QGraphicsItem类,它是界面上的控件,相对于Qt的标准控件,它更省内存。且在中QGraphicsScene中也可以添加QT标准控件。通过addWidget即可。如下

    		QWidget *w = new QWidget ()
            QGraphicsProxyWidget* pwidget = m_mapView->scene()->addWidget(w);
            pwidget->setFlag(QGraphicsItem::ItemIgnoresTransformations, true); //禁止随界面缩放而缩放
            pwidget->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); //禁止随界面大小变化而变化
    
    • 1
    • 2
    • 3
    • 4

    继承QGraphicsItem实现的自定义Item,由于QGraphicsItem它不继承QObject,所有它不具备信号槽机制,如果想要实现信号槽,可以多重继承,既继承QObject,又继承QGraphicsItem,就像QGraphicsObject它一样。

    #ifndef MGRAPHICSITEM_H
    #define MGRAPHICSITEM_H
    
    #include 
    #include 
    #include 
    
    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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    #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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    QSvgRenderer它是用来显示svg矢量图的一个代理类。

  • 相关阅读:
    虚幻引擎图文笔记:动画资源中Force Root Lock的作用
    网络安全漏洞分析与漏洞复现
    vue3+elementUiPlus表格导出功能
    反射
    以太坊合并在即 生态用户需要注意什么?
    海外工具站 2022 复盘:50+ 条所见所思所感
    C++ Reference: Standard C++ Library reference: C Library
    黑豹程序员-CSS四种样式的定义方式及冲突后的就近原则
    PostgreSQL数据库统计信息——analyze命令
    Prophet在R语言中进行时间序列数据预测
  • 原文地址:https://blog.csdn.net/weixin_43246170/article/details/127683120