QGraphicsView使用实例:地图浏览器

mapwidget.h

#pragma once

#include <QGraphicsView>
#include <QLabel>
#include <QMouseEvent>

class MapWidget : public QGraphicsView
{
	Q_OBJECT

public:
	MapWidget();
	~MapWidget();

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

public slots:
	void slotZoom(int value);

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;
};

mapwidget.cpp

#include "mapwidget.h"
#include "qslider.h"
#include <QGridLayout>
#include <QTextStream>
#include "qdebug.h"

MapWidget::MapWidget()
{
	readMap();

	zoom = 50;

	int width = map.width();
	int height = map.height();
	QGraphicsScene *scene = new QGraphicsScene(this);						//新建一个QGraphicsScene对象为主窗口连接一个场景
	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(50);
	connect(slider, SIGNAL(valueChanged(int)), this, SLOT(slotZoom(int)));

	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);

	QFrame *coordFrame = new QFrame;
	coordFrame->setLayout(gridLayout);

	//缩放控制子布局
	QVBoxLayout *zoomLaout = new QVBoxLayout;
	zoomLaout->addWidget(zoominlabel);
	zoomLaout->addWidget(slider);
	zoomLaout->addWidget(zoomoutlabel);

	QVBoxLayout *coordLayout = new QVBoxLayout;
	coordLayout->addWidget(coordFrame);
	coordLayout->addStretch();

	QHBoxLayout *mainLayout = new QHBoxLayout;
	mainLayout->addLayout(zoomLaout);
	mainLayout->addLayout(coordLayout);
	mainLayout->addStretch();
	mainLayout->setMargin(30);
	mainLayout->setSpacing(10);
	setLayout(mainLayout);

	setMinimumSize(600, 400);
}

MapWidget::~MapWidget()
{
}

void MapWidget::readMap()
{
	QString mapName;
	QFile mapFile("maps.txt");
	int ok = mapFile.open(QIODevice::ReadOnly);
	if (ok)
	{
		QTextStream ts(&mapFile);
		if (!ts.atEnd())
		{
			ts >> mapName;
			ts >> x1 >> y1 >> x2 >> y2;
		}
	}
	map.load(mapName);
	if (map.isNull())
	{
		qDebug() << "map is null";
	}
}

QPointF MapWidget::mapToMap(QPointF p)
{
	QPointF latLon;
	int w = sceneRect().width();
	int 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;
}

void MapWidget::slotZoom(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 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);
	mapCoord->setText(QString::number(latLon.x()) + "," + QString::number(latLon.y()));
}

main.cpp

#include "mapwidget.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	MapWidget w;
    w.show();
    return a.exec();
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值