
(源代码和界面之间有一些差异)
参照Linux窗口程序设计---Qt4精彩实例分析中P187的例39"地图浏览器";
和实例不同的是,这里增加了地图的平移功能。在Qt的Demo中,通过setDragMode(QGraphicsView::ScrollHandDrag)即可实现平移,但是,如果需要mouseMoveEvent事件的话,这个方法就不可用,理由如下:

/*gps.h*/
#include <QtGui>
#include "_5waybutton.h"
class Gps:public QGraphicsView
{
Q_OBJECT
public:
Gps();
~Gps();
//
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event);
//
void load_map();
void drawBackground(QPainter *painter, const QRectF &rect);
//
QGraphicsScene *scene;
QPixmap map;
_5WayButton *_5waybutton;
QSlider *slider_zoom;
QFrame *frame_coor;
QLabel *label_coor;
QLabel *label_latitude;
QLabel *label_parallel;
QPoint point_start;
//
int zoom;
int center_x;
int center_y;
public slots:
void slot_zoom(int value);
void slot_up();
void slot_left();
void slot_right();
void slot_down();
void slot_center();
};
/*gps.cpp*/
#include "gps.h"
Gps::Gps()
{
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
load_map();
scene=new QGraphicsScene();
scene->setSceneRect(-map.width()/2,-map.height()/2,map.width(),map.height());
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
setScene(scene);
setRenderHint(QPainter::Antialiasing);
setCacheMode(QGraphicsView::CacheBackground);
//setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
//setDragMode(QGraphicsView::ScrollHandDrag);
//setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
//
QLabel *label_zoomout=new QLabel(tr(" 放大"));
label_zoomout->setFont(QFont("Arial",12,QFont::Bold));
//
QLabel *label_zoomin=new QLabel(tr(" 缩小"));
label_zoomin->setFont(QFont("Arial",12,QFont::Bold));
//
slider_zoom=new QSlider();
slider_zoom->setOrientation(Qt::Vertical);
slider_zoom->setRange(1,400);
slider_zoom->setTickInterval(5);
slider_zoom->setValue(200);
slider_zoom->setFixedSize(40,400);
connect(slider_zoom,SIGNAL(valueChanged(int)),this,SLOT(slot_zoom(int)));
zoom=200;
//
center_x=0;
center_y=0;
//
frame_coor=new QFrame();
//
label_coor=new QLabel(tr("地理坐标"));
label_coor->setFont(QFont("Arial",10,QFont::Bold));
label_latitude=new QLabel(tr("纬度: "));
label_latitude->setFont(QFont("Arial",10,QFont::Bold));
label_parallel=new QLabel(tr("经度: "));
label_parallel->setFont(QFont("Arial",10,QFont::Bold));
//
QVBoxLayout *layout_frame=new QVBoxLayout();
layout_frame->addWidget(label_coor);
layout_frame->addWidget(label_latitude);
layout_frame->addWidget(label_parallel);
frame_coor->setLayout(layout_frame);
//
_5waybutton=new _5WayButton();
connect(_5waybutton->navibutton_up,SIGNAL(clicked()),this,SLOT(slot_up()));
connect(_5waybutton->navibutton_left,SIGNAL(clicked()),this,SLOT(slot_left()));
connect(_5waybutton->navibutton_right,SIGNAL(clicked()),this,SLOT(slot_right()));
connect(_5waybutton->navibutton_down,SIGNAL(clicked()),this,SLOT(slot_down()));
connect(_5waybutton->navibutton_center,SIGNAL(clicked()),this,SLOT(slot_center()));
//
QVBoxLayout *layout_zoom=new QVBoxLayout();
layout_zoom->addWidget(frame_coor);
layout_zoom->addWidget(_5waybutton);
layout_zoom->addWidget(label_zoomout);
layout_zoom->addWidget(slider_zoom);
layout_zoom->addWidget(label_zoomin);
layout_zoom->setSpacing(0);
//
QHBoxLayout *layout_main=new QHBoxLayout();
layout_main->addLayout(layout_zoom);
layout_main->addStretch();
layout_main->setSpacing(0);
setLayout(layout_main);
}
Gps::~Gps()
{
}
void Gps::load_map()
{
map.load(":/image/wuhan.jpg");
}
void Gps::drawBackground(QPainter *painter, const QRectF &rect)
{
painter->drawPixmap(int(sceneRect().left()),int(sceneRect().top()),map);
}
void Gps::slot_zoom(int value)
{
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 Gps::mouseMoveEvent(QMouseEvent *event)
{
QPointF point_scene=this->mapToScene(event->pos());
label_latitude->setText(tr("纬度: ")+QString::number(point_scene.y()+map.height()/2));
label_parallel->setText(tr("经度: ")+QString::number(point_scene.x()+map.width()/2));
if(cursor().shape()==Qt::OpenHandCursor)
{
center_x+=5*(event->pos().x()-point_start.x());
center_x<-map.width()/2?center_x=-map.width()/2:1;
center_x>map.width()/2?center_x=map.width()/2:1;
center_y+=5*(event->pos().y()-point_start.y());
center_y<-map.height()/2?center_y=-map.height()/2:1;
center_y>map.height()/2?center_y=map.height()/2:1;
centerOn(center_x,center_y);
point_start=event->pos();
}
}
void Gps::mousePressEvent(QMouseEvent *event)
{
point_start=event->pos();
setCursor(Qt::OpenHandCursor);
}
void Gps::mouseReleaseEvent(QMouseEvent *event)
{
this->setCursor(Qt::ArrowCursor);
}
void Gps::mouseDoubleClickEvent(QMouseEvent *event)
{
slot_center();
}
void Gps::wheelEvent(QWheelEvent *event)
{
int z=slider_zoom->value()+event->delta()/10;
z>400?z=400:1;
z<1?z=1:1;
this->slider_zoom->setValue(z);
}
void Gps::slot_up()
{
center_y<-map.height()/2?center_y=-map.height()/2:center_y-=map.height()/10;
centerOn(center_x,center_y);
}
void Gps::slot_left()
{
center_x<-map.width()/2?center_x=-map.width()/2:center_x-=map.width()/10;
centerOn(center_x,center_y);
}
void Gps::slot_right()
{
center_x>map.width()/2?center_x=map.width()/2:center_x+=map.width()/10;
centerOn(center_x,center_y);
}
void Gps::slot_down()
{
center_y>map.height()/2?center_y=map.height()/2:center_y+=map.height()/10;
centerOn(center_x,center_y);
}
void Gps::slot_center()
{
slider_zoom->setValue(200);
center_x=0;
center_y=0;
centerOn(center_x,center_y