这个导弹地图是一个中国的地图:
好的废话不多直接上代码(里面有大量注释,不怕你看不懂)
/** * 书本:【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