这个导弹地图是一个中国的地图:
好的废话不多直接上代码(里面有大量注释,不怕你看不懂)
/**
* 书本:【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();
}
/**
* 书本:【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
/**
* 书本:【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;
}
在展示之前,我只想说,有多少是看着 这个标题进来的!!!!!
哈哈,真是为了人气,无所不用其极啊




卧槽,好像又传不了图片了????
答:这个是信号和槽连接的问题,楼主检查是否添加了Q_OBJECT宏?检查一下信号与槽的连接方式是否正确,
处理:在类中添加Q_OBJECT然后qmake一下。
答:map.load(":/China.jpg"); //载入这个文件
首先把这个图载入之后,我们还缺一个操作显示
那就是
voidMapWidget::drawBackground(QPainter*painter,constQRectF&rect)
{
painter->drawPixmap(int(sceneRect().left()),int(sceneRect().top()),map); //画出背景
}
这个可能是在QGraphicsView中显示要有这一步才会显示出来。
假设你的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秒跳一次。我就是举个例子啊,这么跳着的进程条估计很不好看的。。。动的太不平滑
说白了,就是每次跳多少的意思
这个属性控制view的那一部分现在在缓存中,QGraphicsView可以预存一些内容在QPixmap中,然后被绘制到viewpoint 上,这样做的目的是加速整体区域重绘的速度,例如,质地,倾斜度,和最初的混合背景可能重绘很缓慢,尤其是在一个变形的view中, CacheBackground标志使能view的背景缓存,例如
QGraphicsView view;
view.setBackgroundBrush(QImage(":/images/backgroundtile.png"));
view.setCacheMode(QGraphicsView::CacheBackground);
每次view转换后cache就无效了,然而,当滚动区域时候,只有部分无效
默认的,没有使用cache
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的值设定为我们改变之后的值
}
我遇到的一些问题,和处理方法,如上
原文:http://blog.csdn.net/cutter_point/article/details/43162417