码迷,mamicode.com
首页 > 其他好文 > 详细

【Qt5开发及实例】21、导弹地图演示

时间:2015-01-27 09:32:17      阅读:752      评论:0      收藏:0      [点我收藏+]

标签:qt5   实例   地图   浏览器   界面   

导弹地图演示

这个导弹地图是一个中国的地图:












好的废话不多直接上代码(里面有大量注释,不怕你看不懂)

main.cpp

/**
* 书本:【Qt5开发及实例】
* 功能:实现地图的浏览器
* 文件:main.cpp
* 时间:2015年1月26日18:57:55
* 作者:cutter_point
*/
#include "mapwidget.h"

#include <QApplication>
#include <QFont>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  QFont font("迷你简丫丫", 14);    //设置字体和大小
  font.setBold(true);   //加粗
  a.setFont(font);

  MapWidget mapWidget;
  mapWidget.show();   //显示地图

  return a.exec();
}

mapwidget.h

/**
* 书本:【Qt5开发及实例】
* 功能:实现地图的浏览器
* 文件:mapwidget.h
* 时间:2015年1月26日18:57:55
* 作者:cutter_point
*/
#ifndef MAPWIDGET_H
#define MAPWIDGET_H

#include <QGraphicsView>
#include <QLabel>
#include <QMouseEvent>    //鼠标移动

class MapWidget : public QGraphicsView
{
  Q_OBJECT

public:
  MapWidget();

  void readMap();   //读取地图的信息
  QPointF mapToMap(QPointF);    //用于实现场景坐标系和地图坐标系之间的映射,以获得某点的经纬度值

public slots:   //相应的槽函数
  void slotZoom(int);   //响应放大和缩小事件

protected:
  void drawBackground(QPainter *painter, const QRectF &rect);   //完成地图的显示功能呢
  void mouseMoveEvent(QMouseEvent *event);      //鼠标的移动事件

private:
  QPixmap map;    //装载地图信息
  qreal zoom;     //地图的缩放
  QLabel *viewCoord;    //标签
  QLabel *sceneCoord;
  QLabel *mapCoord;
  double x1, y1;
  double x2, y2;


};

#endif // MAPWIDGET_H

mapwidget.cpp

/**
* 书本:【Qt5开发及实例】
* 功能:实现地图的浏览器
* 文件:mapwidget.h
* 时间:2015年1月26日18:57:55
* 作者:cutter_point
*/
#include "mapwidget.h"

#include <QGraphicsScene>
#include <QFile>
#include <QTextStream>
#include <QSlider>    //滑条
#include <QGridLayout>
#include <math.h>
#include <QIcon>
#include <QPixmap>
#include <QDebug>

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);    //设置左上角坐标然后设置长和宽
  //设置当前对象的场景
  this->setScene(scene);
  this->setCacheMode(this->CacheBackground);      //这个是缓存,为了可以说使图像刷新快点

  //用于地图的缩放的滑动条
  QSlider *slider = new QSlider;    //创建一个滑条
  slider->setOrientation(Qt::Vertical);   //设置滑块的方向,这个是垂直的
  slider->setRange(1, 100);     //设置范围
  slider->setTickInterval(10);    //就是每次跳10个大小的意思
  slider->setValue(50);     //滑块的当前值
  connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int)));    //相应的改变

  //两个label
  QLabel *zoominLabel = new QLabel;
  zoominLabel->setScaledContents(true);
  zoominLabel->setPixmap(QPixmap(":/zoomin.png"));

  QLabel *zoomoutLabel = new QLabel;
  zoomoutLabel->setScaledContents(true);
  zoomoutLabel->setPixmap(QPixmap(":/zoomout.png"));

  //坐标值显示区
  QLabel *label1 = new QLabel(tr("GraphicsView:"));
  viewCoord = new QLabel;
  QLabel *label2 = new QLabel(tr("GraphicsScene:"));
  sceneCoord = new QLabel;
  QLabel *label3 = new QLabel(tr("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);   //自动调整到合适的大小

  //创建一个Frame来存放这个布局
  QFrame *coordFrame = new QFrame;
  coordFrame->setLayout(gridLayout);

  //缩放控制子布局
  QVBoxLayout *zoomLayout = new QVBoxLayout;    //垂直布局
  zoomLayout->addWidget(zoominLabel);   //那个放大的图片
  zoomLayout->addWidget(slider);    //中间的滑块
  zoomLayout->addWidget(zoomoutLabel);    //缩小的图片

  //坐标显示区域布局
  QVBoxLayout *coordLayout = new QVBoxLayout;
  coordLayout->addWidget(coordFrame);
  coordLayout->addStretch();    //一个弹簧一样的控件,把其他几个挤到一边

  //主布局
  QHBoxLayout *mainLayout = new QHBoxLayout;    //水平
  mainLayout->addLayout(zoomLayout);
  mainLayout->addLayout(coordLayout);
  mainLayout->addStretch(); //一个弹簧一样的控件,把其他几个挤到一边
  mainLayout->setMargin(30);    //布局外边界的宽度
  mainLayout->setSpacing(10);   //设置之间的间隔
  setLayout(mainLayout);

  setWindowTitle("Map Widget");
  setMinimumSize(600,400);


}

//读取地图
void MapWidget::readMap()
{
  QString mapName;      //地图的名字
  QFile mapFile("maps.txt");      //打开一个文件
  //maps.txt  China.jpg 114.4665527 35.96022297 119.9597168 31.3911575里面依次是地图名,地图左上角经纬值、地图右下角经纬度
  bool ok = mapFile.open(QIODevice::ReadOnly);   //打开文件设置为只读模式
  //如果打开成功
  if(ok)
    {
      QTextStream ts(&mapFile);   //流

      if(!ts.atEnd())
        {
          ts>>mapName;
          ts>>x1>>y1>>x2>>y2;   //依次输入相应的坐标和数据
        }
    }

  map.load(":/China.jpg");      //载入这个文件
}

//地图的缩放
void MapWidget::slotZoom(int value)
{
  qreal s;
  if(value > zoom)
    {
//      s = pow(1.01, (value - zoom));
      s = pow(1.01, (value - zoom));    //1.01的value-zoom次幂,这个基本就是放大1.01倍
    }
  else
    {//基本上是缩小1/1.01
      s = pow(1/1.01, (zoom - value));
    }

  this->scale(s, s);    //前面是水平方向的缩放,后面的是垂直方向的缩放多少倍
  qDebug()<<s<<"---------------";
  zoom = value;   //把zoom的值设定为我们改变之后的值
}

//画出地图
void MapWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
  painter->drawPixmap(int(sceneRect().left()), int(sceneRect().top()), map);    //画出背景
}


//接下来我们显示一下相应的经纬度
void MapWidget::mouseMoveEvent(QMouseEvent *event)
{
  //首先显示层的坐标
  QPoint viewPoint = event->pos();    //鼠标所在
  viewCoord->setText(QString::number(viewPoint.x()) + ", " + QString::number(viewPoint.y()));

  //然后是场景的坐标
  QPointF scenePoint = mapToScene(viewPoint);   //得到映射坐标
  sceneCoord->setText(QString::number(scenePoint.x()) + ", " + QString::number(scenePoint.y()));

  //地图坐标(经,纬度值)
  QPointF latLon = mapToMap(scenePoint);    //根据前面从文件里面读到的坐标xy来觉定
  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 = x1+((w/2+p.x())*abs(x1-x2)/w);

  latLon.setX(lat);
  latLon.setY(lon);

  return latLon;
}





OK,效果展示。


在展示之前,我只想说,有多少是看着 这个标题进来的!!!!!

哈哈,真是为了人气,无所不用其极啊技术分享技术分享技术分享技术分享技术分享技术分享  



卧槽,好像又传不了图片了????


地图浏览器

各种BUG:

 1、error LNK2001: 无法解析的外部符号 "public: virtual struct QMetaObject const * __thiscall

答:这个是信号和槽连接的问题,楼主检查是否添加了Q_OBJECT宏?检查一下信号与槽的连接方式是否正确,

处理:在类中添加Q_OBJECT然后qmake一下。

 

2、Qt无法加载图片QPixmap 对象的load方法??

答:map.load(":/China.jpg");      //载入这个文件

首先把这个图载入之后,我们还缺一个操作显示

 

那就是

voidMapWidget::drawBackground(QPainter*painter,constQRectF&rect)

{

  painter->drawPixmap(int(sceneRect().left()),int(sceneRect().top()),map);    //画出背景

}

这个可能是在QGraphicsView中显示要有这一步才会显示出来。

 

 

3、slider->setTickInterval(10);是什么意思

假设你的slider是100个像素,range是1到100,那么interval是100/100=1
如果slider是100个像素,range是1到1000, ,那么interval是1000/100=10
而mediaObject->setTickInterval(1000);呢就是把interval设为1000,想不出来什么情况用到这么大的interval。。。

追问

不好意思,刚刚学习QT 我是用QT做的视频播放器  ,那interval是什么意思呢?

回答

那个interval也许可以翻成间隔吧,比如你的播放进程,假设媒体是1000秒那么长,而slider是100个像素那么长。要是间隔是10,range是100的话,那个mark就一次跳过10个像素,也就是整个的播放过程就跳10次,也就是100秒跳一次。我就是举个例子啊,这么跳着的进程条估计很不好看的。。。动的太不平滑

 

 

说白了,就是每次跳多少的意思

 

4this->setCacheMode(this->CacheBackground);     

 

 

//这个是缓存,为了可以说使图像刷新快点

 

这个属性控制view的那一部分现在在缓存中,QGraphicsView可以预存一些内容在QPixmap中,然后被绘制到viewpoint 上,这样做的目的是加速整体区域重绘的速度,例如,质地,倾斜度,和最初的混合背景可能重绘很缓慢,尤其是在一个变形的view中, CacheBackground标志使能view的背景缓存,例如

QGraphicsView view;

view.setBackgroundBrush(QImage(":/images/backgroundtile.png"));

view.setCacheMode(QGraphicsView::CacheBackground);

每次view转换后cache就无效了,然而,当滚动区域时候,只有部分无效

默认的,没有使用cache

 

 

5、this->scale(s,s);

void QGraphicsView::scale ( qreal sx, qreal sy )

缩放当前的view,比例是sx,sy

//地图的缩放

voidMapWidget::slotZoom(intvalue)

{

  qreals;

  if(value>zoom)

    {

//      s=pow(1.01,(value-zoom));

      s=pow(1.01,(value-zoom));    //1.01的value-zoom次幂,这个基本就是放大1.01倍

    }

  else

    {//基本上是缩小1/1.01

      s=pow(1/1.01,(zoom-value));

    }

 

  this->scale(s,s);    //前面是水平方向的缩放,后面的是垂直方向的缩放多少倍

  qDebug()<<s<<"---------------";

  zoom=value;   //把zoom的值设定为我们改变之后的值

}

 

我遇到的一些问题,和处理方法,如上




【Qt5开发及实例】21、导弹地图演示

标签:qt5   实例   地图   浏览器   界面   

原文地址:http://blog.csdn.net/cutter_point/article/details/43162417

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!