自定义QGraphicsItem、QGraphicsView绘制运动轨迹

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的简单用法,还需要更深入学习一下
源码下载链接

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值