QGraphicsView实现局部缩放,平移,并且能进行选中数据

前一段时间项目上有个小功能,是加载大批量数据,并且进行绘图显示。以前使用的方法是使用opnegl来进行渲染,效果是有的,但是怎么说呢。总觉得有点大材小用。opengl渲染时,是使用显卡的,不排除有些机器没有显卡。那可能程序就会奔溃。
最新的使用方法是使用graphicview结合paintevent进行绘制图像。
这是绘制图像的代码,通过从文件中读取数据。

qreal scaleFactor = this->matrix().m11();
    sence->clear();
    QImage Img(this->width(),this->height(),QImage::Format_RGB32);
    QPainter painter(&Img);
    painter.setPen(Qt::black);
    QFile file("C:/Users/dujiajun/Desktop/abc.txt");
     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
         return;
     while (!file.atEnd()) {
         QString line = file.readLine();
         line=line.remove(QRegExp("\\s"));
         QStringList strList=line.split(",");
         if(m_SelectPoint.x()<strList[0].toInt()+3&&m_SelectPoint.x()>strList[0].toInt()-2)
         {
            painter.setPen(Qt::red);
         }
         else{
             painter.setPen(Qt::black);
         }
         painter.drawLine(strList[0].toInt(),strList[1].toInt(),strList[2].toInt(),strList[3].toInt());
     }
    QPixmap pixMap=QPixmap::fromImage(Img);
    QGraphicsPixmapItem *item=new QGraphicsPixmapItem();
    item->setPixmap(pixMap);
    sence->addItem(item);

我的数据格式是这样的:
在这里插入图片描述
当然,你也可以自己定义其他数据格式。
然后是局部缩放

QPointF point=event->pos();
    QPointF sencePoint=this->mapToScene(QPoint(point.x(), point.y())); //计算鼠标相对于场景的位置
    qreal width=this->viewport()->width();  //场景宽度
    qreal height=this->viewport()->height(); //场景高度

    //比例计算
    qreal hscale=sencePoint.y()/height;
    qreal wscale=sencePoint.x()/width;

    if(event->delta()>0)
    {
        this->scale(1.2,1.2);
    }
    else
    {
        this->scale(1.0/1.2,1.0/1.2);
    }
    //CreateImage();
    // 将scene坐标转换为放大缩小后的坐标;
    QPointF viewPoint = this->matrix().map(sencePoint);
    //缩放完成之后进行移动位置
    this->horizontalScrollBar()->setValue(int(viewPoint.x()-(width*wscale)));
    this->verticalScrollBar()->setValue(int(viewPoint.y()-(height*hscale)));

进行选中数据及平移数据:

void Widget::mousePressEvent(QMouseEvent *event)
{
    QPointF point=event->pos();
    QPointF sencePoint=this->mapToScene(QPoint(point.x(), point.y()));  //鼠标相对位置
    if(event->button()==Qt::LeftButton)
    {
        m_SelectPoint=sencePoint;
        CreateImage();
    }
    else if(event->button()==Qt::RightButton)
    {
        xo=event->x();
        yo=event->y();
        m_bClicked=true;
    }

}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    int x=event->x();
    int y=event->y();
    if(event->buttons()==Qt::RightButton&&m_bClicked)
    {
        int dx = xo - x;
        int dy = yo - y;
        horizontalScrollBar()->setValue(horizontalScrollBar()->value()+dx);
        verticalScrollBar  ()->setValue(verticalScrollBar  ()->value()+dy);
        xo=x;
        yo=y;
    }
}

完整代码如下:
.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsItem>

class Widget : public QGraphicsView
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void CreateImage();

protected:
    void wheelEvent(QWheelEvent *event);

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);

private:
    QGraphicsItem *m_pGraItem=nullptr;
    bool m_bClicked=false;
    int xo,yo;

    QGraphicsScene *sence=nullptr;

    QPointF m_SelectPoint;

};
#endif // WIDGET_H

.cpp

#include "widget.h"
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QWheelEvent>
#include <QScrollBar>
#include <QMouseEvent>
#include <qdebug.h>
Widget::Widget(QWidget *parent)
    : QGraphicsView(parent)
{
    sence=new QGraphicsScene(this);
    sence->setBackgroundBrush(Qt::red);
    this->setScene(sence);
    CreateImage();
    //item->setPixmap(QPixmap("D:/SVN/EPManager/Image/toolbackground.jpeg"));

}

Widget::~Widget()
{
}

void Widget::CreateImage()
{
    qreal scaleFactor = this->matrix().m11();
    sence->clear();
    QImage Img(this->width(),this->height(),QImage::Format_RGB32);
    QPainter painter(&Img);
    painter.setPen(Qt::black);
    QFile file("C:/Users/dujiajun/Desktop/abc.txt");
     if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
         return;
     while (!file.atEnd()) {
         QString line = file.readLine();
         line=line.remove(QRegExp("\\s"));
         QStringList strList=line.split(",");
         if(m_SelectPoint.x()<strList[0].toInt()+3&&m_SelectPoint.x()>strList[0].toInt()-2)
         {
            painter.setPen(Qt::red);
         }
         else{
             painter.setPen(Qt::black);
         }
         painter.drawLine(strList[0].toInt(),strList[1].toInt(),strList[2].toInt(),strList[3].toInt());
     }
    QPixmap pixMap=QPixmap::fromImage(Img);
    QGraphicsPixmapItem *item=new QGraphicsPixmapItem();
    item->setPixmap(pixMap);
    sence->addItem(item);
}

void Widget::wheelEvent(QWheelEvent *event)
{
    QPointF point=event->pos();
    QPointF sencePoint=this->mapToScene(QPoint(point.x(), point.y())); //计算鼠标相对于场景的位置
    qreal width=this->viewport()->width();  //场景宽度
    qreal height=this->viewport()->height(); //场景高度

    //比例计算
    qreal hscale=sencePoint.y()/height;
    qreal wscale=sencePoint.x()/width;

    if(event->delta()>0)
    {
        this->scale(1.2,1.2);
    }
    else
    {
        this->scale(1.0/1.2,1.0/1.2);
    }
    //CreateImage();
    // 将scene坐标转换为放大缩小后的坐标;
    QPointF viewPoint = this->matrix().map(sencePoint);
    //缩放完成之后进行移动位置
    this->horizontalScrollBar()->setValue(int(viewPoint.x()-(width*wscale)));
    this->verticalScrollBar()->setValue(int(viewPoint.y()-(height*hscale)));


}

void Widget::mousePressEvent(QMouseEvent *event)
{
    QPointF point=event->pos();
    QPointF sencePoint=this->mapToScene(QPoint(point.x(), point.y()));  //鼠标相对位置
    if(event->button()==Qt::LeftButton)
    {
        m_SelectPoint=sencePoint;
        CreateImage();
    }
    else if(event->button()==Qt::RightButton)
    {
        xo=event->x();
        yo=event->y();
        m_bClicked=true;
    }

}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    int x=event->x();
    int y=event->y();
    if(event->buttons()==Qt::RightButton&&m_bClicked)
    {
        int dx = xo - x;
        int dy = yo - y;
        horizontalScrollBar()->setValue(horizontalScrollBar()->value()+dx);
        verticalScrollBar  ()->setValue(verticalScrollBar  ()->value()+dy);
        xo=x;
        yo=y;
    }
}


效果图:
在这里插入图片描述
进行缩放也能精准选中线条。
ヾ( ̄▽ ̄)ByeBye

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加油小杜(接qt定制功能,单模块开发等)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值