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

相关推荐
用户8334423966147 小时前
从批量操作到任务中心,再到现场工作台:DeviceForge v2.10—v2.12 完整演进
qt
宛 禾8 小时前
Qt 控件入门:QLabel 从拖拽到对象树,一篇讲透
c++·qt·学习
打工仔折腾 AI13 小时前
Qt网络编程实战:UDP、TCP到HTTP的落地经验与选型
网络·人工智能·后端·python·qt·udp·ai agent 实战
Lhan.zzZ13 小时前
Linux + Qt/QML:解决 QtQuick.VirtualKeyboard.Plugins 模块加载失败与环境变量配置
linux·数据库·qt
誰能久伴不乏15 小时前
QT工业上位机一次「指令静默丢失」的排查
qt·docker·github
扶尔魔ocy1 天前
【qt openGL入门笔记】OSG实现飞机模型在网格图上飞行并进行态势标绘(四)
qt·opengl·osg
橙橙笔记2 天前
QT安卓软件的制作
android·git·qt·软件
芦芭荞2 天前
QT使用xml模版生成word文档
xml·qt·word
mengzhi啊2 天前
qt把结构体数据存入json文件
qt·json
kaixin_learn_qt_ing2 天前
写入二进制文件(Qt)
qt