QGraphicsItem、QGraphicsView、QGraphicsScene
前言
使用QGraphicsItem、QGraphicsScene、QGraphicsView。主要功能,实现地图的放大、缩小、复位和运动轨迹的显示和清除,根据运动轨迹旋转图片
一、自定义QGraphicsItem
代码如下
graphicsitemairplan.h
#ifndef GRAPHICSITEMAIRPLAN_H
#define GRAPHICSITEMAIRPLAN_H
#include <QObject>
#include <QGraphicsItem>
#include <QPainter>
class GraphicsItemAirPlan : public QObject,public QGraphicsItem
{
Q_OBJECT
public:
explicit GraphicsItemAirPlan(QGraphicsItem *parent = nullptr);
void timerEvent(QTimerEvent *)override;
QRectF boundingRect() const override;
private:
QImage m_Image;
public:
//加载图片
void loadImage(QString strPath);
//图标的大小
QRect getAriPlanRect();
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
signals:
};
#endif // GRAPHICSITEMAIRPLAN_H
graphicsitemairplan.cpp
#include "graphicsitemairplan.h"
GraphicsItemAirPlan::GraphicsItemAirPlan(QGraphicsItem *parent) : QGraphicsItem(parent)
{
}
//加载图片
void GraphicsItemAirPlan::loadImage(QString strPath)
{
m_Image.load(strPath);
}
void GraphicsItemAirPlan::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
//旋转
//setRotation(45);
if (!m_Image.isNull())
painter->drawImage(m_Image.rect(), m_Image);
}
void GraphicsItemAirPlan::timerEvent(QTimerEvent *)
{
}
QRectF GraphicsItemAirPlan::boundingRect() const
{
return m_Image.rect();
}
QRect GraphicsItemAirPlan::getAriPlanRect()
{
return m_Image.rect();
}
二、自定义QGraphicsView
graphicsviewmap.h
#ifndef GRAPHICSVIEWMAP_H
#define GRAPHICSVIEWMAP_H
#include <QObject>
#include <QGraphicsView>
class GraphicsViewMap :public QGraphicsView
{
Q_OBJECT
public:
explicit GraphicsViewMap(QWidget *parent = nullptr);
private:
qreal m_zoomInValue;
qreal m_zoomOutValue;
public:
//放大
void zoomIn();
//缩小
void zoomOut();
//复位
void zoomedRest();
signals:
};
#endif // GRAPHICSVIEWMAP_H
graphicsviewmap.cpp
#include "graphicsviewmap.h"
GraphicsViewMap::GraphicsViewMap(QWidget *parent) : QGraphicsView(parent)
{
//隐藏滚动条
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_zoomInValue = 1.1;
m_zoomOutValue = 0.9;
}
//放大
void GraphicsViewMap::zoomIn()
{
this->scale(m_zoomInValue,m_zoomInValue);
update();
}
//缩小
void GraphicsViewMap::zoomOut()
{
this->scale(m_zoomOutValue,m_zoomOutValue);
update();
}
//复位
void GraphicsViewMap::zoomedRest()
{
this->setTransformationAnchor(QGraphicsView::AnchorViewCenter);
QMatrix q;
q.setMatrix(1,this->matrix().m12(),this->matrix().m21(),1,this->matrix().dx(),this->matrix().dy());
this->setMatrix(q,false);
}
样例
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
init();
showMaximized();
ui->lineEdit->setText("119.814");
ui->lineEdit_2->setText("25.537");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::init()
{
m_itemMap = new DrawItem;
m_itemAirPlan = new GraphicsItemAirPlan;
m_itemPath = new GraphicsItemPath();
m_scene = new QGraphicsScene(ui->widget);
m_viewMap = new GraphicsViewMap(ui->widget);
//加载图片
m_itemMap->loadImage("./Picture/Map/WF.bmp");
m_itemAirPlan->loadImage("./Picture/Map/1.png");
//添加组件
m_scene->addItem(m_itemMap);
m_scene->addItem(m_itemPath);
m_scene->addItem(m_itemAirPlan);
//m_scene->addItem(pGroup);
//设置图层,
m_itemMap->setZValue(0);
m_itemPath->setZValue(2);
m_itemAirPlan->setZValue(1);
//添加场景
m_viewMap->setScene(m_scene);
//重置大小
m_viewMap->resize(ui->widget->width(),ui->widget->height());
//视图可拖动
m_viewMap->setDragMode(QGraphicsView::ScrollHandDrag);
m_viewMap->show();
m_itemPath->m_rect = m_itemMap->getMapRect();
calculateScaleValue(m_itemMap->boundingRect());
}
//放大
void MainWindow::on_pushButton_clicked()
{
m_viewMap->zoomIn();
}
//缩小
void MainWindow::on_pushButton_2_clicked()
{
m_viewMap->zoomOut();
}
//清除轨迹
void MainWindow::on_pushButton_3_clicked()
{
m_itemPath->clearPath();
m_itemPath->update();
}
//复原
void MainWindow::on_pushButton_4_clicked()
{
m_viewMap->zoomedRest();
}
void MainWindow::on_pushButton_5_clicked()
{
float fLongitude,fLattitude;
fLongitude = ui->lineEdit->text().toFloat();
fLattitude = ui->lineEdit_2->text().toFloat();
fLongitude-=0.01;
fLattitude-=0.01;
ui->lineEdit->setText(QString("%1").arg(fLongitude));
ui->lineEdit_2->setText(QString("%1").arg(fLattitude));
QPoint point;
point = getAirPlanPos(fLongitude,fLattitude);
m_itemAirPlan->setPos(point);
//qDebug() << QString("point.x:%1,point.y:%2").arg(point.x()).arg(point.y());
//把点位移动到飞机中心点位
QRect rect = m_itemAirPlan->getAriPlanRect();
point.setX(point.x() + rect.width() / 2);
point.setY(point.y() + rect.height() / 2);
QPointF pointRota = m_itemAirPlan->pos();
//qDebug() << QString("pointRota.x:%1,pointRota.y:%2").arg(pointRota.x()).arg(pointRota.y());
m_itemPath->addPath(point);
m_viewMap->update();
update();
}
/* 获取坐标
* m_fLongitude 经度
* m_fLattitude 纬度
* 返回值 坐标
*/
QPoint MainWindow::getAirPlanPos(float fLongitude,float fLattitude)
{
QPoint point;
double dLongitude,dLattitude;
dLongitude = fLongitude - MINLongitude;
dLattitude = fabs(fLattitude - MAXLattitude);
point.setX (dLongitude * m_scaleLongitude);
point.setY(dLattitude * m_scaleLattitude);
return point;
}
/*根据图片大小、最小经纬度、最大经纬度计算经纬度比例值
*/
void MainWindow::calculateScaleValue(QRectF rect)
{
if(rect.isEmpty())
return;
int nWidth,nHeight;
nWidth = rect.width();
nHeight= rect.height();
float dLongitude,dLattitude;
dLongitude = MAXLongitude - MINLongitude;
dLattitude = MAXLattitude - MINLattitude;
m_scaleLongitude = nWidth / dLongitude;
m_scaleLattitude = nHeight / dLattitude;
}
//角度
void MainWindow::on_pushButton_6_clicked()
{
QRect rect = m_itemAirPlan->getAriPlanRect();
qreal rRotat = ui->lineEdit_3->text().toInt();
m_itemAirPlan->setTransformOriginPoint( rect.width() /2, rect.height() / 2 );
m_itemAirPlan->setRotation(rRotat);
}
//计算角度
void MainWindow::on_pushButton_7_clicked()
{
int nLen = m_itemPath->m_listPointPath.size() - 1;
int nPointX,nPointY,nPointXEnd,nPointYEnd;
nPointX = m_itemPath->m_listPointPath[nLen - 1].x();
nPointY = -m_itemPath->m_listPointPath[nLen - 1].y(); //将坐标值转为第四象限
nPointXEnd = m_itemPath->m_listPointPath[nLen ].x();
nPointYEnd = -m_itemPath->m_listPointPath[nLen ].y(); //将坐标值转为第四象限
int x,y;
x = (nPointXEnd - nPointX );
y = (nPointYEnd - nPointY );
float rRotat;
rRotat= atan2f(y,x);
rRotat = rRotat* 180 / 3.1415926;
qDebug() << rRotat;
QRect rect = m_itemAirPlan->getAriPlanRect();
//设置旋转中心
m_itemAirPlan->setTransformOriginPoint( rect.width() /2, rect.height() / 2 );
m_itemAirPlan->setRotation(rRotat);
}
总结
这只是QGraphicsItem、QGraphicsView的简单用法,还需要更深入学习一下
源码下载链接