QGraphicsView 实例3地图浏览器

主要介绍Graphics View框架,实现地图的浏览、放大、缩小,以及显示各个位置的视图、场景和地图坐标

效果图:

mapwidget.h

#ifndef MAPWIDGET_H
#define MAPWIDGET_H
#include <QLabel>
#include <QMouseEvent>
#include <QGraphicsView>
 
class MapWidget : public QGraphicsView
{
public:
    MapWidget();
     
    void readMap();
    QPointF mapToMap(QPointF);    //实现场景坐标系与地图坐标之间的映射,以获得某点的经纬度值
 
public slots:
    void slotZoom(int);
    QPixmap map;
protected:
    void  drawBackground(QPainter *painter,const QRectF &rect);  //完成地图显示的功能
    
    void  mouseMoveEvent(QMouseEvent * event);
    
private:
 
   qreal zoom;
   QLabel *viewCoord;
   QLabel *sceneCoord;
   QLabel *mapCoord;
   
   double  x1,x2;
   double y1,y2;
 
 
};
 
 
#endif // MAPWIDGET_H

 mapwidget.cpp

#include "mapwidget.h"
#include <QSlider>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFile>
#include <QGraphicsScene>
#include <QTextStream>
#include <math.h>
#include <QLabel>
 
 
/* 1、setCacheMode(CacheBackground)这个属性控制view的那一部分缓存中,QGraphicsView可以预存一些内容在QPixmap中,
* 然后被绘制到viewpoint上,这样做的目的是加速整体区域重绘的速度,例如:质地、倾斜度、和最初的混合背景可能重绘很缓慢,
* 尤其是在一个变形的view中,CacheBackground标志使能view的背景缓存,例如
* QGraphicsView view;
* view.setBackgroundBrush(QImage(":/images/backgroundtile.png"));
* view.setCacheMode(QGraphicsView::CacheBackground);
* 每次view转换后cache就无效了,然而,当滚动区域时候,只有部分无效默认的,没有使用cache
* 2、setTickInterval(int)来设置发射信号的间隔,一般都设置为1000ms,就是1s发射一次
* 3、setScaledContents(bool)这个属性保存标签是否按这个图片的比例填满所用的可用空间,默认false*/
 
MapWidget::MapWidget()
{
    //读取地图信息,包括地图的名称,经纬度等
    readMap();
    zoom=50;
    
    int width=map.width();
    int height=map.height();
    
    QGraphicsScene *scene=new QGraphicsScene(this);
    scene->setSceneRect(-width/2,-height/2,width,height);
    setScene(scene);
    setCacheMode(CacheBackground);
    
    //用于地图缩放的滑动条
    QSlider *slider=new QSlider;
    slider->setOrientation(Qt::Vertical);
    slider->setRange(1,100);
    slider->setTickInterval(10);
    slider->setValue(1);
    connect(slider,&QSlider::valueChanged,[=](int t_value){slotZoom(t_value);});;
    
    QLabel *zoomin=new QLabel;
    zoomin->setScaledContents(true);
    zoomin->setPixmap(QPixmap(":/image/zoomin.jpg"));
    zoomin->setFixedSize(30,30);
 
    QLabel *zoomout=new QLabel;
    zoomout->setScaledContents(true );
    zoomout->setPixmap(QPixmap(":/image/zoomout.jpg"));
    zoomout->setFixedSize(30,30);
    
    //坐标值显示区
    QLabel  *label1=new QLabel(QStringLiteral("QGraphicsView:"));
    viewCoord=new QLabel;
    
    QLabel  *label2=new QLabel(QStringLiteral("QGraphicsScene:"));
    sceneCoord=new QLabel;
    
    QLabel  *label3=new QLabel(QStringLiteral("map:"));
    mapCoord=new QLabel;
    
    //坐标显示区布局
    QGridLayout *gridLayout=new QGridLayout;
    gridLayout->addWidget(label1,0,0);
    gridLayout->addWidget(viewCoord,0,1);
    
    gridLayout->addWidget(label2,1,0);
    gridLayout->addWidget(sceneCoord,1,1);
    
    gridLayout->addWidget(label3,2,0);
    gridLayout->addWidget(mapCoord,2,1);
 
    gridLayout->setSizeConstraint(QLayout::SetFixedSize);
 
    QFrame *coordFrame=new QFrame;
    coordFrame->setLayout(gridLayout);
 
    //坐标显示布局
    QVBoxLayout *coordLayout=new QVBoxLayout;
    coordLayout->addWidget(coordFrame);
    coordLayout->addStretch();
 
    //缩放控制子布局
    QVBoxLayout *zoomlayout=new QVBoxLayout;
    zoomlayout->addWidget(zoomin);
    zoomlayout->addWidget(slider);
    zoomlayout->addWidget(zoomout);
 
    //主布局
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(zoomlayout);
    mainLayout->addLayout(coordLayout);
    mainLayout->addStretch();
    mainLayout->setMargin(30);
    mainLayout->setSpacing(10);
 
    setLayout(mainLayout);
    setWindowTitle(QStringLiteral("Map Widget"));
    setMinimumSize(600,400);
 
}
void MapWidget::readMap()  //读取地图信息
{
 
   QString mapName;
   QFile mapFile(":/image/China.txt");
   int ok=mapFile.open((QIODevice::ReadOnly | QIODevice::Text));  //以"只读"方式打开此文件
 
   if(ok)
    {
      QTextStream ts(&mapFile);
      if(!ts.atEnd())
      {
         ts >> mapName;
         ts>>x1>>y1>>x2>>y2;
 
       }
   }
   mapFile.close();
 
   map.load(":/image/China.jpg");     //将地图读取至私有变量map中
 
}
 
//根据缩放滑动条的当前值,确定当前缩放的比例
void MapWidget::slotZoom(int value)
{
    /*
     * 检测value(slider改变得到的值),与当前value值得大小比较
     * pow(x, y)表示x的y次方
     * slider改变的值大于zoom值时,增加缩放比例
     * slider改变的值小于zoom值时,减小缩放比例
     * scale(s, s)将当前的视图换为(s, s)
     */
 
    qreal s;
    if(value>zoom)  //放大
    {
        s=pow(1.01,(value-zoom));
    }
    else
    {
        s=pow(1/1.01,(zoom-value));
    }
 
    scale(s,s); //实现地图的缩放
    zoom=value;
 
 
}
 
//以地图图片重绘场景的背景来实现地图显示
void MapWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->drawPixmap(int(sceneRect().left()),int(sceneRect().top()),map);
}
 
//完成某点在坐标上的映射和显示
void MapWidget::mouseMoveEvent(QMouseEvent *event)
{
    //QGraphicsView坐标
    QPoint viewpoint=event->pos();
    viewCoord->setText(QString::number(viewpoint.x())+","+QString::number(viewpoint.y()));
 
    //QGraphicsScene坐标
    QPointF scenePoint=mapToScene(viewpoint);
    sceneCoord->setText(QString::number(scenePoint.x())+","+QString::number(scenePoint.y()));
 
   //地图坐标(经纬度)
    QPointF latLon= mapToMap(scenePoint);
    mapCoord->setText(QString::number(latLon.x())+","+QString::number(latLon.y()));
 
 
}
 
QPointF MapWidget::mapToMap(QPointF p)
{
    QPointF latLon;
    qreal w=sceneRect().width();
    qreal h=sceneRect().height();
 
    qreal lon=y1-((h/2+p.y())*abs(y1-y2)/h);
    qreal lat=y1-((w/2+p.x())*abs(x1-x2)/w);
 
    latLon.setX(lat);
    latLon.setY(lon);
    return latLon;
}
 

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QGraphicsView是一个用于显示和编辑大型和复杂的二维图形的类,它是Qt库中的一个重要组件。它提供了一个可视化的视图窗口,其中可以放置QGraphicsItem,并允许用户对这些物品进行操作。 QGraphicsView类提供了许多功能,使得在图形场景中进行交互变得更加容易。通过使用QGraphicsScene类作为场景的模型,可以将各种QGraphicsItem对象添加到场景中。场景然后可以通过QGraphicsView类显示出来。 使用QGraphicsView的好处包括: 1. 支持平移和缩放:QGraphicsView支持对场景进行平移和缩放操作,可以通过鼠标或触摸手势来轻松地在场景中导航和缩放。 2. 支持图形项选择:QGraphicsView提供了一些方法来选择场景中的图形项,可以将选中项高亮显示,并可以对其进行移动、删除等操作。 3. 支持渲染和交互:QGraphicsView可以根据需要重新绘制场景,并捕获用户的交互行为,例如鼠标点击、拖动等。 4. 支持多种视图模式:QGraphicsView提供了几种视图模式,可以进行不同方式的显示,例如普通视图模式、缓存视图模式和OpenGL视图模式等。 5. 提供了自定义功能:QGraphicsView允许用户通过继承和重写其方法来实现自定义的行为和外观,以满足特定的需求。 QGraphicsView是一个功能丰富而强大的类,它为开发者提供了许多工具和方法来处理和显示二维图形。无论是创建绘图应用程序还是设计交互式界面,QGraphicsView都是一个非常有用的类。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值