前一段时间项目上有个小功能,是加载大批量数据,并且进行绘图显示。以前使用的方法是使用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