Qt桌面端地图开发:QWebEngineView加载百度/谷歌地图与双向通信实战

简介:这份资源面向需要在Qt桌面应用中嵌入在线地图的C++开发者,重点解决百度地图与谷歌地图的加载与交互问题。包内共25个文件,以cpp源码、h头文件、html页面、ui界面文件及pro工程文件为主,另含编译生成的obj、exe、pdb等中间产物,压缩包约773KB,可直接参考或二次开发。内容围绕QWebView加载地图URL、通过JavaScript API初始化地图、设置API密钥以及借助javaScriptWindowObject实现C++与JS双向通信等关键环节展开,并附带百度地图与谷歌地图两个HTML示例页面,便于对比两种地图服务的接入差异。已有2697人学习下载,适合具备一定Qt基础、希望快速跑通地图嵌入流程的开发者,可从中获取可运行的工程结构、地图初始化脚本与交互事件处理思路,减少自行摸索API与WebKit集成的时间成本。

1. 当你的桌面端项目需要一张能交互的地图

做过桌面端上位机或者工具软件的开发者大概都遇到过这种需求:设备上报的 GPS 坐标要在地图上实时打点,或者物流调度系统里要画出车辆轨迹,再或者只是想在界面里嵌一张能缩放、能拖拽的地图做区域选择。这时候如果项目用的是 Qt,第一反应往往是——Qt 自带的 QtLocation 模块能不能直接用?答案是能,但配置起来相当折腾,插件依赖、瓦片源、网络策略每一项都可能卡住半天。

这份资源走的是另一条路:绕开 QtLocation 的插件体系,直接用 QWebEngineView 加载网页版地图,通过 Qt 与 JavaScript 的双向通信来控制地图行为。百度地图和谷歌地图两套都做了适配,切换地图源只需要改一个配置项。适合正在做 Qt 桌面项目、需要在界面里嵌入交互地图、又不想被 QtLocation 的插件配置折磨的开发者。下面从项目结构开始拆。

2. 项目结构与技术选型:为什么用 QWebEngineView 而不是 QtLocation

2.1 两套方案的取舍

Qt 官方提供的 QtLocation 模块理论上可以加载在线地图,但它依赖 GeoServicePlugin,不同平台下可用的插件不一样,而且瓦片源的配置需要写 QML 或者 C++ 插件。更麻烦的是,QtLocation 对国内地图服务商的支持几乎为零,百度地图、高德地图都没有现成的插件可用。你当然可以自己写一个 GeoServicePlugin,但那工作量已经超过项目本身了。

QWebEngineView 的方案本质上是把地图当成一个网页来加载。百度地图和谷歌地图都有成熟的 JavaScript API,网页端能做的事,QWebEngineView 里都能做。Qt 侧只需要负责两件事:把地图页面加载进来,以及通过 QWebChannel 或者 runJavaScript 与页面里的 JS 通信。这个思路的好处是地图的所有交互逻辑(缩放、拖拽、标注、路线规划)都由地图 JS API 处理,Qt 侧只关心业务数据。

代价也有:QWebEngineView 会引入 Chromium 内核,编译出来的程序体积会增加大概 100MB 左右。如果你的项目对安装包体积极度敏感,这个方案需要权衡。但对于大多数桌面工具软件来说,这个体积是可以接受的。

2.2 目录结构

项目的目录组织大致如下:

QtMapDemo/ ├── QtMapDemo.pro # qmake 工程文件 ├── main.cpp # 程序入口 ├── mainwindow.h/cpp/ui # 主窗口 ├── mapview.h/cpp # 地图控件封装 ├── mapbridge.h/cpp # Qt 与 JS 通信桥接 ├── html/ │ ├── baidu_map.html # 百度地图页面 │ ├── google_map.html # 谷歌地图页面 │ └── qwebchannel.js # QWebChannel 前端库 └── config/ └── map_config.ini # 地图源与密钥配置

核心文件是 mapview 和 mapbridge 两个类。mapview 继承自 QWebEngineView,负责页面加载和生命周期管理;mapbridge 是一个 QObject 子类,注册到 QWebChannel 里,暴露槽函数给 JS 调用,同时提供信号让 Qt 侧接收 JS 的回调。

2.3 工程配置

.pro 文件里需要启用 webengine 模块:

QT += core gui webenginewidgets webchannel network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = QtMapDemo TEMPLATE = app CONFIG += c++17 SOURCES += main.cpp mainwindow.cpp mapview.cpp mapbridge.cpp HEADERS += mainwindow.h mapview.h mapbridge.h FORMS += mainwindow.ui RESOURCES += resources.qrc

这里有几个点需要注意。webenginewidgets 和 webchannel 是两个独立的模块,都要加。network 模块虽然 QWebEngineView 内部会用到,但如果你要在 Qt 侧发 HTTP 请求获取坐标数据,也需要显式声明。c++17 不是必须的,但 QWebChannel 的一些新特性在 C++17 下用起来更顺手。

注意:Qt 5.15 之后 webenginewidgets 从 QtWebEngine 拆成了独立模块,如果你用的是 Qt 6,模块名和头文件路径会有变化,需要确认 Qt 版本。

3. 地图加载核心实现:从 QWebEngineView 初始化到页面渲染

3.1 MapView 类的初始化

MapView 继承 QWebEngineView,构造函数里完成页面加载和通道建立:

// mapview.h class MapView : public QWebEngineView { Q_OBJECT public: explicit MapView(QWidget *parent = nullptr); void loadMap(MapType type); // 切换地图源 void setCenter(double lng, double lat); void addMarker(double lng, double lat, const QString &label); signals: void mapReady(); void markerClicked(int id); private: MapBridge *m_bridge; QWebChannel *m_channel; MapType m_currentType; };
// mapview.cpp MapView::MapView(QWidget *parent) : QWebEngineView(parent) , m_currentType(MapType::Baidu) { // 创建通信桥接对象 m_bridge = new MapBridge(this); m_channel = new QWebChannel(this); m_channel->registerObject("mapBridge", m_bridge); // 将通道设置到页面 page()->setWebChannel(m_channel); // 允许本地文件访问远程资源 page()->settings()->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true); // 连接桥接信号 connect(m_bridge, &MapBridge::mapInitialized, this, &MapView::mapReady); connect(m_bridge, &MapBridge::markerClicked, this, &MapView::markerClicked); }

这段代码的关键在于 QWebChannel 的注册时机。必须在页面加载之前把 bridge 对象注册进去,否则 HTML 里的 qwebchannel.js 初始化时找不到对象。另一个容易忽略的是 LocalContentCanAccessRemoteUrls 这个设置,因为 HTML 文件是从本地资源加载的,但地图瓦片和 API 脚本来自远程服务器,不开这个选项页面会一片空白。

3.2 百度地图页面的加载逻辑

百度地图的 HTML 页面结构:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="qwebchannel.js"></script> <script src="https://api.map.baidu.com/api?v=3.0&ak=YOUR_AK"></script> </head> <body style="margin:0;padding:0;"> <div id="map_container" style="width:100%;height:100%;"></div> <script> var map, bridge; function initMap() { map = new BMap.Map("map_container"); var point = new BMap.Point(116.404, 39.915); map.centerAndZoom(point, 12); map.enableScrollWheelZoom(true); // 建立 Qt 通信通道 new QWebChannel(qt.webChannelTransport, function(channel) { bridge = channel.objects.mapBridge; bridge.mapInitialized(); }); } // 供 Qt 调用的全局函数 function setCenter(lng, lat) { if (!map) return; map.setCenter(new BMap.Point(lng, lat)); } function addMarker(lng, lat, label) { if (!map) return; var point = new BMap.Point(lng, lat); var marker = new BMap.Marker(point); map.addOverlay(marker); if (label) { var labelObj = new BMap.Label(label, { offset: new BMap.Size(20, -10) }); marker.setLabel(labelObj); } marker.addEventListener("click", function() { bridge.markerClicked(marker.getId()); }); } window.onload = initMap; </script> </body> </html>

这里有几个设计决策值得说明。initMap 放在 window.onload 里而不是立即执行,是因为百度地图 API 脚本是异步加载的,如果 DOM 还没准备好就调用 BMap.Map 会报错。QWebChannel 的初始化放在地图初始化之后,确保 bridge 对象可用时地图已经就绪。

addMarker 函数里给 marker 绑定了 click 事件,通过 bridge.markerClicked 把点击事件传回 Qt 侧。这里传的是 marker 的 id,Qt 侧可以根据 id 找到对应的业务数据。注意 bridge.markerClicked 是直接调用 QWebChannel 暴露的方法,不需要额外的信号连接。

3.3 谷歌地图页面的差异处理

谷歌地图的 JS API 与百度地图在接口设计上有明显差异:

<script> var map, bridge; function initMap() { map = new google.maps.Map(document.getElementById("map_container"), { center: {lat: 39.915, lng: 116.404}, zoom: 12, disableDefaultUI: false, scrollwheel: true }); new QWebChannel(qt.webChannelTransport, function(channel) { bridge = channel.objects.mapBridge; bridge.mapInitialized(); }); } function setCenter(lng, lat) { if (!map) return; map.setCenter({lat: lat, lng: lng}); } function addMarker(lng, lat, label) { if (!map) return; var marker = new google.maps.Marker({ position: {lat: lat, lng: lng}, map: map, title: label || "" }); marker.addListener("click", function() { bridge.markerClicked(marker.get("id") || 0); }); } </script> <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=initMap" async defer></script>

谷歌地图的坐标参数是对象形式 {lat, lng},而百度地图是 BMap.Point(lng, lat),注意经纬度顺序也不一样。谷歌地图的 API 加载用 callback 参数指定初始化函数,比百度地图的 window.onload 更规范一些。marker 的点击事件用 addListener 而不是 addEventListener,这是谷歌地图自己的事件系统。

3.4 Qt 侧调用 JS 函数

MapView 提供的方法通过 runJavaScript 调用页面里的全局函数:

void MapView::setCenter(double lng, double lat) { QString js = QString("setCenter(%1, %2)") .arg(lng, 0, 'f', 6) .arg(lat, 0, 'f', 6); page()->runJavaScript(js); } void MapView::addMarker(double lng, double lat, const QString &label) { QString js = QString("addMarker(%1, %2, '%3')") .arg(lng, 0, 'f', 6) .arg(lat, 0, 'f', 6) .arg(label); page()->runJavaScript(js); }

runJavaScript 是异步执行的,不会阻塞 Qt 主线程。参数格式化时经纬度保留 6 位小数,这是地图 API 的常见精度要求。label 参数直接拼接到 JS 字符串里,如果 label 包含单引号会导致语法错误,实际项目中需要做转义处理。

提示:runJavaScript 的第二个参数可以传一个回调函数,用来接收 JS 的返回值。如果需要获取地图当前中心点坐标,可以用这个方式。

4. Qt 与 JavaScript 双向通信:QWebChannel 桥接的完整链路

4.1 MapBridge 类的设计

MapBridge 是 Qt 侧和 JS 侧通信的核心,它继承 QObject 并暴露给 QWebChannel:

// mapbridge.h class MapBridge : public QObject { Q_OBJECT public: explicit MapBridge(QObject *parent = nullptr); signals: void mapInitialized(); void markerClicked(int id); void mapClicked(double lng, double lat); public slots: void onMapReady(); // JS 通知地图就绪 void onMarkerClicked(int id); // JS 通知标注被点击 void onMapClicked(double lng, double lat); // JS 通知地图被点击 QString getMapType(); // JS 查询当前地图类型 };
// mapbridge.cpp MapBridge::MapBridge(QObject *parent) : QObject(parent) { } void MapBridge::onMapReady() { emit mapInitialized(); } void MapBridge::onMarkerClicked(int id) { emit markerClicked(id); } void MapBridge::onMapClicked(double lng, double lat) { emit mapClicked(lng, lat); } QString MapBridge::getMapType() { // 从配置读取当前地图类型 QSettings settings("config/map_config.ini", QSettings::IniFormat); return settings.value("map/type", "baidu").toString(); }

这里的设计模式是:JS 侧调用 bridge 的 public slots 方法,MapBridge 把这些调用转换成 Qt 信号发出去,MapView 或者 MainWindow 连接这些信号做业务处理。getMapType 是一个同步方法,JS 调用后会立即返回结果,适合查询配置类数据。

4.2 JS 侧调用 Qt 方法

在 HTML 页面里,通过 bridge 对象调用 Qt 侧的槽函数:

// JS 通知 Qt 地图已就绪 bridge.onMapReady(); // JS 通知 Qt 标注被点击 bridge.onMarkerClicked(42); // JS 通知 Qt 地图被点击(带经纬度) map.addEventListener("click", function(e) { bridge.onMapClicked(e.point.lng, e.point.lat); }); // JS 查询 Qt 侧配置 bridge.getMapType(function(result) { console.log("当前地图类型:", result); });

注意 getMapType 的调用方式和其他方法不同。有返回值的方法在 QWebChannel 里是异步的,需要通过回调函数接收结果。这个设计一开始容易踩坑,以为能直接 var type = bridge.getMapType(),实际上拿到的是 undefined。

4.3 地图源切换的完整流程

切换地图源需要重新加载页面并重新建立通道:

void MapView::loadMap(MapType type) { m_currentType = type; QString htmlFile; switch (type) { case MapType::Baidu: htmlFile = "qrc:/html/baidu_map.html"; break; case MapType::Google: htmlFile = "qrc:/html/google_map.html"; break; } // 重新注册通道(页面重载后旧通道失效) m_channel = new QWebChannel(this); m_channel->registerObject("mapBridge", m_bridge); page()->setWebChannel(m_channel); // 加载新页面 QUrl url(htmlFile); page()->load(url); }

每次切换地图源都重新创建 QWebChannel 并注册 bridge,这是因为页面重载后旧的通道对象已经失效。如果不重新注册,新页面里的 qwebchannel.js 会连接失败,表现为 bridge 为 null,所有通信中断。

4.4 通信链路的数据流

整个通信链路可以这样理解:Qt 侧调用 page()->runJavaScript() 执行 JS 全局函数,这是 Qt 到 JS 的方向;JS 侧通过 bridge 对象调用 Qt 槽函数,这是 JS 到 Qt 的方向。两个方向都是异步的,Qt 侧不需要等待 JS 执行完成,JS 侧调用 Qt 方法也不会阻塞页面渲染。

这种异步特性在大多数场景下没问题,但如果你需要确保某个操作执行完成后再进行下一步,就需要用回调或者信号来同步。比如加载地图后立即添加标注,如果地图还没初始化完成就调用 addMarker,JS 侧会因为 map 变量为 null 而静默失败。正确的做法是等 mapInitialized 信号触发后再执行后续操作。

5. 避坑与常见问题排查

5.1 页面白屏或地图不显示

现象:QWebEngineView 加载后一片空白,控制台没有明显报错。

原因通常有三个:一是 LocalContentCanAccessRemoteUrls 没有开启,本地 HTML 无法加载远程的地图 API 脚本;二是 API 密钥无效或过期,百度地图和谷歌地图都会返回鉴权失败;三是网络请求被拦截,某些企业网络环境会屏蔽地图服务域名。

解决方法是先在 QWebEngineView 里打开开发者工具(通过 page()->setDevToolsPage() 或者环境变量 QTWEBENGINE_REMOTE_DEBUGGING),看 Network 面板里 API 脚本是否加载成功。如果返回 403 就是密钥问题,如果请求根本没发出去就是网络策略问题。

5.2 QWebChannel 连接失败

现象:JS 侧 bridge 对象为 null,调用 bridge 的任何方法都报错。

原因:QWebChannel 的注册时机不对,或者页面重载后没有重新注册。另一个常见原因是 qwebchannel.js 文件没有正确加载,这个文件需要从 Qt 安装目录复制到项目资源里,不能从 CDN 加载。

解决:确认 page()->setWebChannel() 在 page()->load() 之前调用。如果是页面重载场景,每次 load 之前都要重新 setWebChannel。qwebchannel.js 建议直接嵌入 HTML 或者通过 qrc 资源加载,不要依赖网络。

5.3 经纬度坐标偏移

现象:标注打点位置和实际位置有几百米偏差。

原因:国内地图服务商使用的坐标系不同。百度地图用 BD-09,谷歌地图用 WGS-84,高德地图用 GCJ-02。如果数据源是 GPS 原始坐标(WGS-84),直接放到百度地图上就会有偏移。

解决:在 Qt 侧做坐标转换,或者在 JS 侧调用地图 API 提供的转换接口。百度地图有 BMap.Convertor 可以做坐标转换,谷歌地图需要自己实现 WGS-84 到 GCJ-02 的转换算法。建议在数据进入地图之前统一转成目标地图的坐标系。

5.4 程序打包后地图加载失败

现象:开发环境正常,打包发布后地图不显示。

原因:qrc 资源里的 HTML 文件路径在打包后可能变化,或者 qwebchannel.js 没有被正确打包。另一个可能是 QtWebEngineProcess 可执行文件没有被部署到正确位置。

解决:用 windeployqt 工具自动部署依赖,确认 QtWebEngineProcess.exe 和相关 DLL 在发布目录里。qrc 资源路径用 :/ 前缀而不是 qrc:/,虽然两者在开发环境都能用,但打包后 :/ 更可靠。

5.5 runJavaScript 执行无效果

现象:调用 runJavaScript 后页面没有任何变化,也没有报错。

原因:JS 函数名拼写错误、参数类型不匹配、或者函数还没定义就调用了。runJavaScript 是异步的,执行失败不会在 Qt 侧抛出异常。

解决:在 runJavaScript 的回调里打印返回值,确认 JS 是否执行。或者在 JS 函数里加 console.log,通过开发者工具查看。确保调用的全局函数在 window 对象上,而不是在某个闭包里。

6. 二次开发改造:从 Demo 到可维护的地图模块

拿到这个项目之后,最直接的改造方向是把它封装成一个可复用的地图控件。我一般会做这几件事。

第一,把地图配置抽成独立的配置文件。API 密钥、默认中心点、默认缩放级别、地图类型这些都放到 ini 或者 json 里,不要硬编码在代码里。这样换一个项目只需要改配置,不用动代码。

// 配置读取示例 QSettings settings("config/map_config.ini", QSettings::IniFormat); QString ak = settings.value("baidu/ak").toString(); double defaultLng = settings.value("map/default_lng", 116.404).toDouble(); double defaultLat = settings.value("map/default_lat", 39.915).toDouble(); int defaultZoom = settings.value("map/default_zoom", 12).toInt();

第二,把地图操作封装成业务友好的接口。不要在上层代码里直接拼 JS 字符串,而是提供 addMarker(MarkerData)、drawPolyline(QList ) 这样的方法。MarkerData 里包含经纬度、标题、图标、自定义数据等字段,MapView 内部负责转换成 JS 调用。

第三,处理地图加载的异步时序。提供一个 whenReady() 方法返回 QFuture 或者用信号通知,确保上层代码在地图初始化完成后再执行操作。我见过太多项目在地图还没加载完就调 addMarker,然后排查半天为什么标注不显示。

第四,考虑离线场景。如果项目部署环境没有外网,需要提前下载地图瓦片或者使用离线地图方案。百度地图有离线 SDK,但配置比较复杂。一个折中方案是在内网部署一个瓦片代理服务,QWebEngineView 加载的 HTML 里把瓦片地址指向内网服务器。

第五,日志和调试。QWebEngineView 的 console.log 默认不会输出到 Qt 的日志系统,需要重写 QWebEnginePage::javaScriptConsoleMessage 把 JS 日志转发到 Qt 侧。这个在排查问题时非常有用。

class MapPage : public QWebEnginePage { protected: void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString &message, int lineNumber, const QString &sourceID) override { qDebug() << "[JS]" << sourceID << ":" << lineNumber << message; } };

从那以后我每次做地图相关的项目,都会先把 console 转发和配置外置这两件事做了,后面省下来的排查时间远超前期投入。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

LM4040AIM3-3.0+T微功耗3V基准芯片选型与设计实战

LM4040AIM3-3.0+T微功耗3V基准芯片选型与设计实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/21 2:11:47 阅读更多 →
电赛轮腿式平衡小车:串级PID与运动学解耦实战

电赛轮腿式平衡小车:串级PID与运动学解耦实战

简介&#xff1a;这份资源是面向电子设计竞赛参赛者、自动控制与机器人方向学生的轮腿式自平衡小车完整项目包&#xff0c;聚焦动态平衡原理与嵌入式控制实践。压缩包共1311个文件&#xff0c;约49.48MB&#xff0c;以C源码&#xff08;619个&#xff09;和头文件&#xff08;3…

2026/10/21 2:10:47 阅读更多 →
抖音主页批量下载无水印视频:douyin-downloader 3 步跑通完整教程

抖音主页批量下载无水印视频:douyin-downloader 3 步跑通完整教程

抖音主页批量下载无水印视频&#xff1a;douyin-downloader 3 步跑通完整教程 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fal…

2026/10/21 2:10:47 阅读更多 →

最新新闻

51单片机贪吃蛇实战:12864驱动、EEPROM掉电保存与嵌入式分层设计

51单片机贪吃蛇实战:12864驱动、EEPROM掉电保存与嵌入式分层设计

简介&#xff1a;本资源是一套面向大学本科课程设计的51单片机贪吃蛇游戏完整开发方案&#xff0c;适用于单片机原理与应用、嵌入式系统实践等课程学习与项目实训。资源包含Proteus仿真工程&#xff08;.pdsprj&#xff09;、Keil C51源码&#xff08;.c/.a51&#xff09;、编译…

2026/10/21 3:32:25 阅读更多 →
图书推荐系统实战:Python协同过滤从原理到代码避坑指南

图书推荐系统实战:Python协同过滤从原理到代码避坑指南

我记得第一次带学生跑这个图书推荐系统项目时&#xff0c;好几个人卡在了同一个地方&#xff1a;代码能跑通&#xff0c;但推荐结果全是乱的。后来查了半天&#xff0c;问题出在一个被注释掉的函数上。这个项目在中文互联网上流传了很多版本&#xff0c;绝大多数人拿到的都是简…

2026/10/21 3:32:25 阅读更多 →
空间注意力模块实战指南:原理、代码与调参经验

空间注意力模块实战指南:原理、代码与调参经验

做视觉任务这些年&#xff0c;大家都会遇到一个很实际的需求&#xff1a;网络深了、宽了&#xff0c;但该学的东西没学会。SpatialAttention空间注意力模块&#xff0c;是我调过的结构里性价比最高的一个——代码就几十行、参数量几乎可以忽略&#xff0c;却能明显改变网络的关…

2026/10/21 3:32:25 阅读更多 →
awesome-shizuku vs Dhizuku:两大Android权限提升工具终极对比指南

awesome-shizuku vs Dhizuku:两大Android权限提升工具终极对比指南

awesome-shizuku vs Dhizuku&#xff1a;两大Android权限提升工具终极对比指南 在Android开发的世界中&#xff0c;awesome-shizuku和Dhizuku是两个备受关注的高权限工具&#xff0c;它们都致力于让普通应用获得系统级权限&#xff0c;从而突破Android系统的限制。无论你是普通…

2026/10/21 3:32:25 阅读更多 →
CANN内测实战:从环境初始化到模型推理的完整指南

CANN内测实战:从环境初始化到模型推理的完整指南

前阵子看到某社区的“内测招募&#xff0c;免费体验CANN开发环境”活动&#xff0c;我第一时间就报名了。说实话&#xff0c;当时打动我的不只是“免费”两个字&#xff0c;而是想看看这个面向昇腾AI处理器的异构计算架构&#xff0c;在过去一年里到底进化到了什么程度。CANN这…

2026/10/21 3:32:25 阅读更多 →
Redis单线程还是多线程?从4.0到7.2的线程模型演进真相

Redis单线程还是多线程?从4.0到7.2的线程模型演进真相

1. 这个问题为什么值得花十分钟认真搞懂“Redis 到底是单线程还是多线程&#xff1f;”——这句提问在技术群、面试现场、甚至线上课程评论区里&#xff0c;几乎每周都会高频出现。它表面看是个“是非题”&#xff0c;但背后牵扯的是你对 Redis 性能本质、架构演进逻辑、以及高…

2026/10/21 3:31:24 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →