当前位置: 首页 > ai >正文

QgraphicsView异步线程加载地图瓦片

        本节主要记录一下qt开发过程中离线地图瓦片的加载方式,瓦片加载选择graphicsView控件,同时为了不影响主线程事件和其他操作,这里采用了异步线程的操作,将地图瓦片加载的步骤放到了异步子线程之中。注:本记录仅为本人笔记记录。

 一、效果展示

二、代码展示

        1、思路

        设计中,我们先选择graphicsView放置与ui设计界面,以作为瓦片的存放容器。

        创建子线程:线程功能实现为筛选对应坐标编号的地图瓦片信息并传递给主线程进行显示

        主线程:开启子线程的运行,并获取子线程传递的对应瓦片地图信息进行显示。

        2、子线程代码实现

#ifndef MAPWORK_H
#define MAPWORK_H#include <QObject>
#include <QPixmap>
#include <QFile>
class mapWork : public QObject
{  Q_OBJECT
public:explicit mapWork(int zoom, int tileSize, QObject *parent = nullptr): QObject(parent), m_zoom(zoom), m_tileSize(tileSize) {}public slots://自定义函数,是实现瓦片的查找和加载void loadTiles(int xStart, int xEnd, int yStart, int yEnd, const QString& basePath) {//X层级和y层级代表地图瓦片编号相对应的层级for(int x = xStart; x < xEnd; ++x) {for(int y = yStart; y < yEnd; ++y) {//我的瓦片图文件存放在程序目录下的mapabc目录,satellite目录对应的是卫星地图瓦片,overlay目录对应的是街道瓦片数据//先加载卫星瓦片地图QString filename_1 = QString("%1/mapabc/satellite/%2/%3/%4.jpg").arg(basePath).arg(m_zoom).arg(x).arg(y);if(QFile::exists(filename_1)) {QPixmap pixmap(filename_1);if(!pixmap.isNull()) {emit tileLoaded(x, y, pixmap);//发送瓦片数据信息  对应的层级和图片文件}//加载街道地图瓦片QString filename_2 = QString("%1/mapabc/overlay/%2/%3/%4.png").arg(basePath).arg(m_zoom).arg(x).arg(y);if(QFile::exists(filename_2)) {QPixmap pixmap2(filename_2);if(!pixmap.isNull()) {emit tileLoaded(x, y, pixmap2);//发送瓦片数据信息  对应的层级和图片文件}}}}emit finished();}}signals:void tileLoaded(int x, int y, const QPixmap& pixmap);  //定义信号,传递主线程对应的瓦片信息void finished();private:int m_zoom;  //瓦片层级int m_tileSize; //瓦片的大小 256*256,此处为256
};#endif // MAPWORK_H

3、主函数代码功能实现

mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QGraphicsScene> //场景
#include <QGraphicsView>  //视图
#include <QGraphicsItem>  //图元
#include <QDir>
#include "mapwork.h"
#include <QThread>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:void setMap();
private slots:void addTileToScene(int x, int y, const QPixmap& pixmap);private:void setupThread();Ui::MainWindow *ui;QGraphicsScene *myScene;//map 线程加载mapWork *m_worker;QThread *m_workerThread;//map相关int zoom = 14;//地图层级int wap_X_start = 13373; //x层级瓦片和y层级瓦片的开始结束标号int wap_X_end = 13604;int wap_Y_start = 6123;int wap_Y_end = 6290;//程序路径QDir currentDir = QDir::current();int tileSize = 256;//每个瓦片的像素边长 256*256
};
#endif // MAINWINDOW_H

mainwindow.cpp文件

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow),zoom(14),currentDir(QDir::current()),tileSize(256)
{ui->setupUi(this);setupThread();//进入线程加载图片//场景设置myScene = new QGraphicsScene(this);//初始化视图ui->graphicsView->setScene(myScene);ui->graphicsView->setRenderHint(QPainter::SmoothPixmapTransform);ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground);setMap();
}
MainWindow::~MainWindow()
{delete ui;if(m_workerThread && m_workerThread->isRunning()) {qDebug() << "Stopping worker thread...";m_workerThread->quit();if(!m_workerThread->wait(3000)) {qCritical() << "线程未正常退出,强制终止";m_workerThread->terminate();}}
}
void MainWindow::setupThread()
{m_workerThread = new QThread(this);m_worker = new mapWork(zoom, tileSize);m_worker->moveToThread(m_workerThread);// 完整信号连接connect(m_worker, &mapWork::tileLoaded,this, &MainWindow::addTileToScene);connect(m_workerThread, &QThread::finished,m_worker, &QObject::deleteLater);m_workerThread->start();
}void MainWindow::setMap()
{const QString basePath = currentDir.absolutePath();//线程安全QMetaObject::invokeMethod(m_worker, "loadTiles", Qt::QueuedConnection,Q_ARG(int, wap_X_start),Q_ARG(int, wap_X_end),Q_ARG(int, wap_Y_start),Q_ARG(int, wap_Y_end),Q_ARG(QString, basePath));
}
//插入图片元素
void MainWindow::addTileToScene(int x, int y, const QPixmap& pixmap)
{QGraphicsPixmapItem* item = myScene->addPixmap(pixmap);item->setPos(x * tileSize, y * tileSize);
}

 

http://www.xdnf.cn/news/2685.html

相关文章:

  • 【LInux网络】数据链路层 - 深度理解以太网和APR协议
  • gdb 源码安装
  • 软考-软件设计师中级备考 5、数据结构 树和二叉树
  • Improving Deep Learning For Airbnb Search
  • linux常用操作命令
  • 小草GrassRouter多卡聚合路由器聚合卫星、MESH网络应用解决方案
  • Prompt
  • 多元复合函数求导的三种情况
  • STM32 ADC模数转换器
  • 企业用电管理革新利器 —— Acrel-3000 电能管理系统应用解析
  • SpringBoot 接口国际化i18n 多语言返回 中英文切换 全球化 语言切换
  • 群创5.6寸TFT液晶屏AT056TN53-5.6寸显示模组
  • nginx.exe打不开或者打开后浏览器显示连接出错
  • Qt开发环境的安装与问题的解决(2)
  • 代码随想录算法训练营Day34 | 62.不同路径 63. 不同路径II 343.整数拆分 96.不同的二叉搜索树
  • 【Light文献速览】湖南大学超表面高阶庞加莱球偏振检测时钟技术突破
  • 02.06、回文链表
  • C# wpf
  • mysql community 8.0.23升级到8.0.42再到8.4.5
  • 架构师与高级工程师:职业差异与进阶之路
  • C++ —— 正向迭代器与反向迭代器
  • 5000元可以运行32B大模型的笔记本
  • Shell脚本-嵌套循环应用案例
  • vue mixin混入与hook
  • 如何使用可视化工具分析 JVM 的性能瓶颈?
  • Spring Security授权管理
  • 综合练习一
  • JAVA基础:Collections 工具类实战指南-从排序到线程安全
  • ViTa-Zero:零样本视觉触觉目标 6D 姿态估计
  • Ubuntu深度学习革命:NVIDIA-Docker终极指南与创新实践