QGraphicsView 实例3地图浏览器

主要介绍Graphics View框架,实现地图的浏览、放大、缩小,以及显示各个位置的视图、场景和地图坐标

效果图:

mapwidget.h

#ifndef MAPWIDGET_H
#define MAPWIDGET_H
#include <QLabel>
#include <QMouseEvent>
#include <QGraphicsView>
 
class MapWidget : public QGraphicsView
{
public:
    MapWidget();
     
    void readMap();
    QPointF mapToMap(QPointF);    //实现场景坐标系与地图坐标之间的映射,以获得某点的经纬度值
 
public slots:
    void slotZoom(int);
    QPixmap map;
protected:
    void  drawBackground(QPainter *painter,const QRectF &rect);  //完成地图显示的功能
    
    void  mouseMoveEvent(QMouseEvent * event);
    
private:
 
   qreal zoom;
   QLabel *viewCoord;
   QLabel *sceneCoord;
   QLabel *mapCoord;
   
   double  x1,x2;
   double y1,y2;
 
 
};
 
 
#endif // MAPWIDGET_H

 mapwidget.cpp

#include "mapwidget.h"
#include <QSlider>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFile>
#include <QGraphicsScene>
#include <QTextStream>
#include <math.h>
#include <QLabel>
 
 
/* 1、setCacheMode(CacheBackground)这个属性控制view的那一部分缓存中,QGraphicsView可以预存一些内容在QPixmap中,
* 然后被绘制到viewpoint上,这样做的目的是加速整体区域重绘的速度,例如:质地、倾斜度、和最初的混合背景可能重绘很缓慢,
* 尤其是在一个变形的view中,CacheBackground标志使能view的背景缓存,例如
* QGraphicsView view;
* view.setBackgroundBrush(QImage(":/images/backgroundtile.png"));
* view.setCacheMode(QGraphicsView::CacheBackground);
* 每次view转换后cache就无效了,然而,当滚动区域时候,只有部分无效默认的,没有使用cache
* 2、setTickInterval(int)来设置发射信号的间隔,一般都设置为1000ms,就是1s发射一次
* 3、setScaledContents(bool)这个属性保存标签是否按这个图片的比例填满所用的可用空间,默认false*/
 
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);
    setScene(scene);
    setCacheMode(CacheBackground);
    
    //用于地图缩放的滑动条
    QSlider *slider=new QSlider;
    slider->setOrientation(Qt::Vertical);
    slider->setRange(1,100);
    slider->setTickInterval(10);
    slider->setValue(1);
    connect(slider,&QSlider::valueChanged,[=](int t_value){slotZoom(t_value);});;
    
    QLabel *zoomin=new QLabel;
    zoomin->setScaledContents(true);
    zoomin->setPixmap(QPixmap(":/image/zoomin.jpg"));
    zoomin->setFixedSize(30,30);
 
    QLabel *zoomout=new QLabel;
    zoomout->setScaledContents(true );
    zoomout->setPixmap(QPixmap(":/image/zoomout.jpg"));
    zoomout->setFixedSize(30,30);
    
    //坐标值显示区
    QLabel  *label1=new QLabel(QStringLiteral("QGraphicsView:"));
    viewCoord=new QLabel;
    
    QLabel  *label2=new QLabel(QStringLiteral("QGraphicsScene:"));
    sceneCoord=new QLabel;
    
    QLabel  *label3=new QLabel(QStringLiteral("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 *coordLayout=new QVBoxLayout;
    coordLayout->addWidget(coordFrame);
    coordLayout->addStretch();
 
    //缩放控制子布局
    QVBoxLayout *zoomlayout=new QVBoxLayout;
    zoomlayout->addWidget(zoomin);
    zoomlayout->addWidget(slider);
    zoomlayout->addWidget(zoomout);
 
    //主布局
    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(zoomlayout);
    mainLayout->addLayout(coordLayout);
    mainLayout->addStretch();
    mainLayout->setMargin(30);
    mainLayout->setSpacing(10);
 
    setLayout(mainLayout);
    setWindowTitle(QStringLiteral("Map Widget"));
    setMinimumSize(600,400);
 
}
void MapWidget::readMap()  //读取地图信息
{
 
   QString mapName;
   QFile mapFile(":/image/China.txt");
   int ok=mapFile.open((QIODevice::ReadOnly | QIODevice::Text));  //以"只读"方式打开此文件
 
   if(ok)
    {
      QTextStream ts(&mapFile);
      if(!ts.atEnd())
      {
         ts >> mapName;
         ts>>x1>>y1>>x2>>y2;
 
       }
   }
   mapFile.close();
 
   map.load(":/image/China.jpg");     //将地图读取至私有变量map中
 
}
 
//根据缩放滑动条的当前值,确定当前缩放的比例
void MapWidget::slotZoom(int value)
{
    /*
     * 检测value(slider改变得到的值),与当前value值得大小比较
     * pow(x, y)表示x的y次方
     * slider改变的值大于zoom值时,增加缩放比例
     * slider改变的值小于zoom值时,减小缩放比例
     * scale(s, s)将当前的视图换为(s, s)
     */
 
    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)
{
    //QGraphicsView坐标
    QPoint viewpoint=event->pos();
    viewCoord->setText(QString::number(viewpoint.x())+","+QString::number(viewpoint.y()));
 
    //QGraphicsScene坐标
    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()));
 
 
}
 
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=y1-((w/2+p.x())*abs(x1-x2)/w);
 
    latLon.setX(lat);
    latLon.setY(lon);
    return latLon;
}
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/480975.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tomcat 服务器部署和 IDEA 配置 Tomcat

(一) Tomcat 简介 Tomcat是Apache软件基金会一个核心项目&#xff0c;是一个开源免费的轻量级Web服务器&#xff0c;支持Servlet/JSP少量JavaEE规范。 概念中提到了JavaEE规范&#xff0c;那什么又是JavaEE规范呢? JavaEE: Java Enterprise Edition,Java企业版。指Java企业级…

【Java初阶(二)】分支与循环

❣博主主页: 33的博客❣ ▶文章专栏分类: Java从入门到精通◀ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; 目录 1.前言2.顺序结构3.分支循环3.1if语句3.2switch语句 4.循环结构4.1while循环4.2 break和continue4.3 for循环4.4 do while循环 5.输入输出5.1输出5.2输…

三级数据库技术知识点(详解!!!)

1、从功能角度数据库应用系统可以划分为表示层、业务逻辑层、数据访问层、数据持久层四个层次&#xff0c;其中负责向表示层直接传送数据的是业务逻辑层。 【解析】表示层负责所有与用户交互的功能;业务逻辑层负责根据业务逻辑需要将表示层获取的数据进行组织后&#xff0c;传…

提升Midjourney风格化的三个技巧

1. 引言 在前篇博文中&#xff0c;我们详细讲述了Midjourney的新功能风格参考的一些基础使用方法&#xff0c;事实上我们可以通过控制参数和提示权重进行更多的自定义操作&#xff0c;在本文中&#xff0c;我将向大家介绍我在网上搜集到的一些提升风格化效果的三个技巧。 闲话…

阿里云服务器租用一年多少钱?2024年最新阿里云租用价格

2024年阿里云服务器租用费用&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元&#xff0c;ECS u1服务器2核4G5M固定带宽199元一年&#xff0c;2核4G4M带宽轻量服务器一年165元12个月&#xff0c;2核4G服务…

NC 现金流量查询 节点 多账簿联查时,根据所选择的列来判断明细和现金流量联查按钮是否可用,根据添加列选择监听事件处理。

NC 现金流量查询 节点 多账簿联查时&#xff0c;根据所选择的列来判断明细和现金流量联查按钮是否可用&#xff0c;如下图的情况&#xff1a; 在现金流量查询界面UI类的initTable(QueryConditionVO conVO)方法中添加列选择监听事件即可&#xff0c;如下&#xff1a; // 列监听…

【Android】【Bluetooth Stack】蓝牙电话协议之拨打电话分析(超详细)

1. 精讲蓝牙协议栈&#xff08;Bluetooth Stack&#xff09;&#xff1a;SPP/A2DP/AVRCP/HFP/PBAP/IAP2/HID/MAP/OPP/PAN/GATTC/GATTS/HOGP等协议理论 2. 欢迎大家关注和订阅&#xff0c;【蓝牙协议栈】和【Android Bluetooth Stack】专栏会持续更新中.....敬请期待&#xff01…

【Spring框架】单元测试:JUnit

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

Filter介绍使用案例

文章目录 一、Filter概念二、Filter快速入门定义类&#xff0c;实现Filter接口&#xff0c;并重写其所有方法 三、Filter执行流程四、Filter使用细节1、Filter拦截路径配置2、过滤器链 五、案例 一、Filter概念 二、Filter快速入门 定义类&#xff0c;实现Filter接口&#xff0…

cc-inputSelView:使用uni-app和原生input组件实现用户位置选择功能

摘要&#xff1a; 在前端开发中&#xff0c;为用户提供选择位置的功能是一个常见的需求。本文将介绍如何使用uni-app和原生input组件实现用户位置选择功能&#xff0c;包括地图定位和页面跳转选择数据两种方式。通过这种方式&#xff0c;开发者可以轻松地为用户提供便利的位置选…

基于Java-SpringBoot+vue实现的前后端分离信息管理系统设计和实现

基于Java-SpringBootvue实现的前后端分离信息管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

停车场引导和道闸系统工程

在当今快速发展的都市环境中&#xff0c;停车场不再是简单的泊车空间&#xff0c;而是需要智能化、高效化的管理来满足日益增长的车辆需求。现代电子信息技术的融入使得停车场引导和道闸系统工程成为可能&#xff0c;为城市交通带来革命性的变化。本文将概述这一系统的主要组成…

为什么光模块会发生故障?

当SFP光模块发生故障时&#xff0c;技术人员需要立即找出原因并进行修复&#xff0c;否则&#xff0c;1G链路可能会中断。本指南将为初次接触光模块领域的企业提供一些SFP光模块修复解决方案的支持。 SFP光模块故障的主要原因 SFP光模块故障通常发生在发送端和接收端。最常见…

C++之constexpr和常量表达式

常量表达式 常量表达式(const expression)是指值不会改变并且在编译过程就能得到计算结果的表达式。 显然&#xff0c;字面值属于常量表达式&#xff0c;用常量表达式初始化的const对象也是常量表达式。 后面将会提到&#xff0c;C语言中有几种情况下是要用到常量表达式的。…

35 跨域相关问题, 以及常见的解决方式

前言 跨域相关 这是一个 经常会碰到的问题 然后 常见的解决方式 也大概就是几种, 各有各的问题 这里仅仅是 从理论上 来探讨这个问题 主流的解决方式 是通过代理, 将不同域 合并到同一个域 测试用例 测试用例如下, 这里仅仅是一个简单的数据展示 获取对方 “/config.jso…

由浅到深认识Java语言(17):内部类

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

python框架的一加剧场管理系统的设计与实现flask-django-nodejs-php

本文讲述了一加剧场管理系统。结合电子管理系统的特点&#xff0c;分析了一加剧场管理系统的背景&#xff0c;给出了一加剧场管理系统实现的设计方案。 本论文主要完成不同用户的权限划分&#xff0c;不同用户具有不同权限的操作功能&#xff0c;在用户模块&#xff0c;主要有用…

mysql之基本概念与安装

一 数据库的基本概念 1.1 数据 记录个体的信息 1.2 表 存放信息的集合&#xff0c;行于与列 1.3 数据库 数据库就是表的集合。它是以一定的组织方式存储的相互有关的数据集合 1.4 数据库管理系统 数据库管理系统&#xff08;DatabaseManagementSystem&#xff0c;DBMS&…

MySQL面试题--开发(最全,涵盖SQL基础、架构、事务)

MySQL面试题--事务https://mp.csdn.net/mp_blog/creation/editor/136947072 MySQL面试题--MySQL内部技术架构https://blog.csdn.net/Timebro/article/details/136946046?spm1001.2014.3001.5501 MySQL面试题--最全面-索引https://blog.csdn.net/Timebro/article/details/136…

深度学习基础之《TensorFlow框架(10)—案例:实现线性回归(2)》

增加其他功能 一、增加变量显示 1、目的&#xff1a;在TensorBoard当中观察模型的参数、损失值等变量值的变化 2、收集变量 不同的变量要用不同的方式收集 &#xff08;1&#xff09;tf.summary.scalar(name, tensor) 收集对于损失函数和准确率等单值变量&#xff0c;name为…