From b772b5a16929afd6df09ae1a9a08eb5ea3bbf470 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Thu, 11 Jun 2026 14:47:19 +0800 Subject: [PATCH] =?UTF-8?q?build(qwt):=20=E9=9B=86=E6=88=90=20Qwt=206.2=20?= =?UTF-8?q?=E9=9D=99=E6=80=81=E5=BA=93(cmake/qwt.cmake=20=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E5=AE=98=E6=96=B9Qt6,=E7=BB=95=E5=BC=80qmake/vcpkg)?= =?UTF-8?q?=20+=20=E5=86=92=E7=83=9F=E7=94=A8=E4=BE=8B=20+=20=E8=BF=94?= =?UTF-8?q?=E5=B7=A5=E6=96=B9=E6=A1=88=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 二维图表返工前置:QwtPlot 作科学图表框架。源码 external/qwt-src(gitignore)按 ENV_SETUP 拉取。 --- CMakeLists.txt | 6 + cmake/qwt.cmake | 29 +++ docs/Geopro3.0_二维图表返工技术方案.md | 234 +++++++++++++++++++++++++ tests/CMakeLists.txt | 6 + tests/render/test_qwt_smoke.cpp | 10 ++ 5 files changed, 285 insertions(+) create mode 100644 cmake/qwt.cmake create mode 100644 docs/Geopro3.0_二维图表返工技术方案.md create mode 100644 tests/render/test_qwt_smoke.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index da3abd8..82853d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,12 @@ FetchContent_Declare(qtkeychain GIT_TAG v0.14.0) FetchContent_MakeAvailable(qtkeychain) +# Qwt 6.2(二维科学图表:数据集详情散点/等值线图)。见 cmake/qwt.cmake 说明。 +# 源码 external/qwt-src 已 gitignore,需按 docs/ENV_SETUP 拉取。 +if(EXISTS "${CMAKE_SOURCE_DIR}/external/qwt-src/src") + include("${CMAKE_SOURCE_DIR}/cmake/qwt.cmake") +endif() + add_subdirectory(src) enable_testing() diff --git a/cmake/qwt.cmake b/cmake/qwt.cmake new file mode 100644 index 0000000..9ffd2ca --- /dev/null +++ b/cmake/qwt.cmake @@ -0,0 +1,29 @@ +# 定义 qwt 静态库目标(Qwt 6.2 二维科学图表:数据集详情散点/等值线图)。 +# +# 为何不用 Qwt 原生 qmake:本机 VS2026 预览版缺 vswhere,qmake 探测 cl 失败。 +# 为何不用 vcpkg 的 qwt:其端口依赖 vcpkg-qtbase,会与官方 Qt 形成双 Qt 冲突(项目铁律: +# 依赖 Qt 的组件不走 vcpkg)。故此处用 CMake 直接编 Qwt 源码,对接官方 Qt6(同 VTK 思路)。 +# +# 源码目录 external/qwt-src(已 gitignore,按 docs/ENV_SETUP 拉取): +# git clone --depth 1 https://github.com/opencor/qwt external/qwt-src # Qwt 6.2.0 镜像 +# 由根 CMakeLists 在源码存在时 include 本文件。 + +set(QWT_SRC_DIR "${CMAKE_SOURCE_DIR}/external/qwt-src/src") + +find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent PrintSupport Svg) + +file(GLOB _qwt_sources CONFIGURE_DEPENDS "${QWT_SRC_DIR}/*.cpp") +file(GLOB _qwt_headers CONFIGURE_DEPENDS "${QWT_SRC_DIR}/*.h") +# 排除:OpenGL 画布 / SVG plot item / QwtPolar 部件(避免额外模块依赖与面积)。 +# 保留 qwt_symbol.cpp(用 QSvgRenderer,故链 Qt6::Svg)与 qwt_point_polar.cpp(几何工具)。 +list(FILTER _qwt_sources EXCLUDE REGEX "qwt_plot_glcanvas|qwt_plot_opengl_canvas|qwt_plot_svgitem|qwt_polar_") +list(FILTER _qwt_headers EXCLUDE REGEX "qwt_plot_glcanvas|qwt_plot_opengl_canvas|qwt_plot_svgitem|qwt_polar_") + +add_library(qwt STATIC ${_qwt_sources} ${_qwt_headers}) +set_target_properties(qwt PROPERTIES AUTOMOC ON) +target_include_directories(qwt PUBLIC "${QWT_SRC_DIR}") +target_link_libraries(qwt PUBLIC Qt6::Widgets Qt6::Concurrent Qt6::PrintSupport Qt6::Svg) +target_compile_features(qwt PUBLIC cxx_std_17) +if(MSVC) + target_compile_options(qwt PRIVATE /bigobj /EHsc /wd4244 /wd4267 /wd4305 /wd4456) +endif() diff --git a/docs/Geopro3.0_二维图表返工技术方案.md b/docs/Geopro3.0_二维图表返工技术方案.md new file mode 100644 index 0000000..380596f --- /dev/null +++ b/docs/Geopro3.0_二维图表返工技术方案.md @@ -0,0 +1,234 @@ +# Geopro 3.0 桌面客户端 — 数据集详情「二维图表」返工技术方案 + +**版本 v1.0** · 适用范围:数据集详情页的「原数据(散点图)」与「网格数据(填充等值线图)」 +**状态**:返工指令(推翻当前 QGraphicsView 实现,重做) + +--- + +## 0. 给开发(含 AI 编码)的硬约束 — 先读这一段 + +1. **不嵌入 QWebEngine,不引入 Chromium。** 整个客户端的技术路线是 Qt C++ 原生,核心动机包含离线/现场作业能力;把核心数据可视化做成依赖 web 渲染会破坏该前提,禁止。 +2. **推翻当前的裸 `QGraphicsView` + VTK 渲染窗口方案。** 当前 9 个问题的根因是 2D 框架选错,不是"没嵌 web"。 +3. **改用 `QwtPlot` 作为两类图的坐标系框架;等值线多边形用 VTK 算法(仅算法,不开 VTK 渲染窗口)。** +4. **验收标准 = 视觉等价 + 交互一致**,不是字节级像素 diff。原生渲染与 web 端 Plotly 在抗锯齿、字体、亚像素上天生有别,任何工具都无法字节级相同;目标是"用户看不出降级感"。 +5. **不要自由发挥架构。** 本文档把分层、类、职责定死,照做;遇到本文档未覆盖的细节,先问,不要自行另起一套。 + +--- + +## 1. 根因诊断(为什么会做崩) + +当前实现把"图形 + 坐标轴 + 色阶图例"全部糊在一个 `QGraphicsView` 场景里一起做变换,导致系统性错误。裸 `QGraphicsView` 是通用图形框架,**不具备"科学图表"语义**——它不知道什么是固定坐标轴、什么是"仅数据区缩放"、什么是"图例不参与变换"。 + +把用户列的 9 个问题按根因归类: + +| # | 问题 | 根因类别 | 由谁解决 | +|---|---|---|---| +| 1 | 色阶图随大图缩放、与横坐标重叠 | 框架(图例未独立) | QwtPlot 分层 | +| 3 | 拖动时坐标轴跟着动(应只动数据、轴值跟随) | 框架(无数据区/轴分离) | QwtPlot 内置交互 | +| 4 | 一拖动画面就花 | 框架(手写变换 + 重绘错误) | QwtPlot 内置交互 | +| 9 | 图比原版瘦(纵横比错) | 框架(无纵横比控制) | QwtPlot 纵横比锁定 | +| 2 | 配色与原版不一致(离散色带 vs 连续插值) | 实现细节(色阶映射) | QwtLinearColorMap | +| 5 | 等值线数字没显示 | 实现细节(缺标注) | 等值线 label | +| 6 | 原数据/网格数据切换样式被改错 | UI 布局(与图表无关) | 改回页签样式 | +| 7 | 显示异常/等值线开关跑到面板外 | UI 布局(与图表无关) | 归位工具条 | +| 8 | 下方缺「描述」页签 | UI 布局(与图表无关) | 补页签 | + +**关键结论**:9 个问题没有一个需要"嵌 web"才能解决。第 1 类(#1/#3/#4/#9)换对框架即消失;第 2 类(#2/#5)是渲染细节;第 3 类(#6/#7/#8)是纯 UI,跟用什么画图无关。 + +--- + +## 2. 目标架构 — 三层分离 + +整个二维图表 widget 必须做成**三层分离**,这是治本: + +``` +┌─────────────────────────────────────────────┐ +│ ChartPanel (QWidget) │ +│ ┌───────────────────────────────────────┐ │ +│ │ 工具条 ToolBar(网格/色阶配置/白化/...) │ │ ← 工具条层(属于面板,不属于绘图区) +│ ├───────────────────────────────────────┤ │ +│ │ QwtPlot(数据区 + 固定坐标轴) │ │ ← 绘图层(QwtPlot 管坐标轴与交互) +│ │ • QwtPlotItem: 等值线多边形 / 散点 │ │ +│ │ • QwtPlotMagnifier / Panner(交互) │ │ +│ ├───────────────────────────────────────┤ │ +│ │ ColorBarWidget(独立固定) │ │ ← 图例层(独立 widget,永不参与数据区变换) +│ └───────────────────────────────────────┘ │ +└─────────────────────────────────────────────┘ +``` + +**铁律**: +- **坐标轴**由 QwtPlot 管理,**永远固定**(不随拖动移动其位置),拖动/缩放时只有**数据区内容**平移缩放,**轴上的刻度数值自动跟随重算**。这正是 QwtPlot 的默认行为,也正是原版的行为。 +- **色阶条(ColorBar)是独立 widget**,放在绘图区下方,**绝不放进 QwtPlot 的数据坐标系**,因此永远不会随图缩放、不会和横坐标重叠(直接消灭 #1)。 +- **工具条属于面板**,不属于绘图区(修正 #7)。 + +--- + +## 3. 框架与依赖 + +| 用途 | 选用 | 协议 | 说明 | +|---|---|---|---| +| 2D 图表坐标系框架 | **QwtPlot(Qwt 6.2+)** | QWT License(LGPL + 例外,商用免费) | 坐标轴、缩放、平移、刻度跟随、图例、色阶映射全内置 | +| 等值线多边形算法 | **vtkBandedPolyDataContourFilter** | BSD(商用免费) | 仅当算法用,**不开 VTK 渲染窗口** | +| 等值线(线)算法 | vtkContourFilter / vtkFlyingEdges2D | BSD | 生成等值线及其标注位置 | +| 连续色阶映射 | **QwtLinearColorMap** | QWT License | 对齐原版 Plotly 的连续插值色阶 | + +> 协议全部商用友好,零授权费。QWT 与 VTK 都不触发开源传染。 + +> **VTK 的双重角色**(务必理解,否则又会做重):在 3D 视图 / 地图视图里 VTK 是**渲染器**(开渲染窗口);在本页这种纯二维详情图里,VTK **退化为算法库**(只用它的 filter 算多边形,取出顶点交给 QwtPlot 画)。本页**不允许**出现 QVTKOpenGLWidget / 渲染窗口。 + +--- + +## 4. 逐项解法(对应 9 个问题) + +### 4.1 色阶条独立固定(治 #1) + +- 新建 `ColorBarWidget : public QWidget`,自绘一条水平色带 + 刻度数值 + 单位。 +- 它在布局上位于 QwtPlot **下方**,是**兄弟 widget**,不是 QwtPlot 的内部 item。 +- 它的色阶**与绘图区用同一个色阶对象**(见 §6 色阶服务),保证图与图例配色一致。 +- 因为它不在数据坐标系内,**永远不随拖动/缩放移动,不会与横坐标轴重叠**。 +- 刻度数值与原版对齐:用与数据相同的分级断点(原版色阶断点形如 17.105 / 25.937 / ...,等比/对数分布,见 §6)。 + +### 4.2 仅数据区缩放、坐标轴固定、轴值跟随(治 #3) + +- 用 QwtPlot,坐标轴(`QwtPlot::xBottom` / `yLeft`)由 QwtPlot 框架绘制,位置固定。 +- 缩放/平移用 QwtPlot 内置: + - `QwtPlotMagnifier`(滚轮缩放数据区) + - `QwtPlotPanner`(拖动平移数据区) + - 需要框选缩放可加 `QwtPlotZoomer` +- 这些组件只改变**坐标轴的数值范围(scaleDiv)**,QwtPlot 自动重算刻度并重绘——**轴不动、轴上的数字跟着变**,与原版完全一致。 +- **原数据 = 四象限坐标系**(数据含正负,x/y 轴交叉于原点区域);**网格数据 = 单象限**(数据全正,原点在左下)。在 QwtPlot 里就是设置不同的轴范围与原点位置,不需要两套框架。 + +### 4.3 拖动不再花屏(治 #4) + +- 当前"花屏"是手写 `QGraphicsView` 变换 + 重绘时机错误导致。改用 QwtPlot 后,重绘由 QwtPlot 的 replot 机制统一管理,不会出现脏区残留。 +- 大数据量等值线多边形若导致拖动卡顿:对 `QwtPlotItem` 开启 `QwtPlotItem::RenderAntialiased` 视情况关闭、并启用绘制缓存;必要时对多边形做 LOD 简化(与原版"简化容差"滑块一致,见 §7)。 + +### 4.4 纵横比 / 宽度修正(治 #9) + +- 原版图是"宽扁"的剖面图(x 范围远大于 y)。当前实现"偏瘦"是因为没有锁定数据纵横比、或 widget 尺寸策略错误。 +- 解法:根据数据的 x/y 跨度设定数据区的纵横比;若要求等比例(1 个数据单位 x = 1 个数据单位 y 的像素),自定义布局在 replot 时按数据范围调整 canvas 的宽高比,或固定 y 轴范围、x 轴自适应填充。 +- 先对齐原版的"宽扁"观感即可,不必强制物理等比,除非业务要求等比例尺。 + +### 4.5 连续插值色阶,对齐 Plotly 配色(治 #2) + +- 原版散点/等值线用的是**连续插值色阶**(Plotly 的 colorscale),当前实现用了**离散色带**,所以配色不同。 +- 用 `QwtLinearColorMap`,设置与原版相同的**控制点颜色 + 位置**,开启连续插值(`QwtLinearColorMap` 默认 `ScaledColors` 连续模式,不要用 `FixedColors`)。 +- 控制点取自原版色阶(紫蓝→蓝→青→绿→黄→橙→红→深红的彩虹序列)。**必须从原版抓取实际色值**(见 §6 第 4 步),不要凭记忆配色。 +- 色阶分布是**对数/等比**的(断点 17.105, 25.937, 34.382... 比值递增),映射时对数据取 log 再线性映射,否则颜色分布会与原版不同。 + +### 4.6 等值线数值标注(治 #5) + +- 等值线(contour line)由 `vtkContourFilter` 在各分级阈值生成线,取出线的折点。 +- 在 QwtPlot 中用自定义 `QwtPlotItem` 绘制这些线,并在线的合适位置绘制数值标签(label):沿线取中点或曲率较小处,绘制旋转贴合线方向的文本(原版标签是贴着等值线方向旋转的)。 +- 受工具条「显示等值线标注」复选框控制开关。 +- 「显示等值线提示信息」控制 hover 时的 tooltip(鼠标移到等值线上显示数值),与原版一致。 + +### 4.7 页签切换样式归位(治 #6) + +- 「原数据 / 网格数据」切换**不是两个按钮**,而是与「数据集面板的 数据/文件」「右栏的 异常/对象属性」**同一种下划线页签样式**(之前已专门调过样式,复用那套 QSS/组件,不要重写成 QPushButton)。 +- 直接复用既有的下划线 Tab 组件类,保证全客户端切换样式统一。 + +### 4.8 工具条归位到网格数据面板内(治 #7) + +- 「显示异常 / 显示等值线标注 / 显示等值线提示信息 / 简化容差滑块 / 网格 / 色阶配置 / 白化 / 滤波处理 / 异常标注 / 自动标注 / 另存为」这些**属于网格数据视图的工具条**,必须在网格数据面板**内部**的工具条上,不能浮到外层。 +- 「原数据」页签的工具条是另一套(网格 / 色阶配置 / 当前图形下拉 / 另存为),各自归属各自页签。 + +### 4.9 下方补「描述」页签(治 #8) + +- 图下方区域是一个含两个页签的容器:**「异常列表」+「描述」**,当前只做了异常列表表格,缺「描述」。 +- 补上「描述」页签(富文本/纯文本说明区),与原版结构一致。 + +--- + +## 5. 组件清单与职责(定死,不要改结构) + +| 类 | 基类 | 职责 | +|---|---|---| +| `DatasetDetailPanel` | QWidget | 数据集详情页根容器:顶部下划线页签(原数据/网格数据)+ 内容区 + 下方(异常列表/描述)| +| `RawDataChartView` | QWidget | 「原数据」散点图:工具条 + QwtPlot(四象限)+ ColorBar | +| `GridDataChartView` | QWidget | 「网格数据」等值线图:工具条 + QwtPlot(单象限)+ ColorBar | +| `ContourPlotItem` | QwtPlotItem | 自定义:绘制 VTK 算出的分层填充多边形 + 等值线 + 标注 | +| `ScatterPlotItem` | QwtPlotItem / QwtPlotSpectroCurve | 散点,按值连续着色 | +| `ColorBarWidget` | QWidget | 独立色阶条(固定,不入数据坐标系)| +| `ColorMapService` | (单例/服务) | 全局色阶:断点、颜色、命名保存、对数映射;图与图例同源 | +| `ContourEngine` | (封装 VTK) | 输入网格数据 → 输出分层多边形 + 等值线折点(封装 vtkBandedPolyDataContourFilter / vtkContourFilter)| + +--- + +## 6. 色阶服务(对齐原版的关键) + +色阶是"配色一致"的命门,单独抽成服务,**图、图例、3D 视图共用同一份**(呼应视觉设计规范 §8): + +1. **断点(分级阈值)**:采用原版的对数/等比分布。原版断点示例:`17.105, 25.937, 34.382, 35.972, 42.555, 49.051, 56.312, 68.950, 83.029, 98.454, 110.570, 129.660, 158.270, 204.160, 260.820, 321.710, 1335.500`(不同数据集断点不同,应由数据的 min/max + 分级规则动态生成,规则与原版一致)。 +2. **颜色控制点**:彩虹序列(深蓝 → 蓝 → 亮蓝 → 青 → 浅绿 → 绿 → 黄绿 → 黄 → 土黄 → 橙 → 黄 → 红 → 深红 → 紫红 → 紫 → 深紫黑)。 +3. **映射方式**:连续插值(`QwtLinearColorMap` ScaledColors)+ 对数标度(数据先 log,再线性映射到 [0,1])。 +4. **必须从原版抓真实色值**:打开原版页面 `http://tenant.geomative.cn/#/projectSpace/datasetMange/datasetInfo?id=...&ddCode=dd_inversion_data`,用浏览器开发者工具检查 Plotly 的 `colorscale` 配置,或对色阶条截图取色(每个色块取中心像素 RGB)。**严禁凭记忆配色** —— 这是 #2 反复出错的根源。 +5. **命名保存**:色阶可命名、保存、切换,调整后图与图例实时刷新(业务规约要求)。 + +--- + +## 7. 工具条功能对照(两个页签各一套) + +**原数据页签工具条**:网格 | 色阶配置 | 当前图形(下拉:散点图/...)| 另存为 + +**网格数据页签工具条**:网格 | 色阶配置 | 白化 | 滤波处理 | ☑显示异常 | ☑显示等值线标注 | ☐显示等值线提示信息 | 简化容差(滑块,0–1)| 异常标注 | 自动标注 | 另存为 + +- 「简化容差」滑块:控制等值线多边形的简化程度(值越大,多边形越简化、越平滑),对应 VTK 侧对多边形做 `vtkDecimatePolylineFilter` 或道格拉斯-普克简化的容差参数。 +- 「白化」「滤波处理」是对网格数据的预处理操作,作用于 ContourEngine 的输入。 +- 「自动标注」弹出对话框(见 §8)。 + +--- + +## 8. 自动标注对话框(复用同一图表组件) + +- 「自动标注」弹出的对话框里那张图,**必须与主页面网格数据图完全一致**——做法是**复用同一个 `GridDataChartView` / `ContourPlotItem` 类的另一个实例**,传入同一份数据 + 同一个 ColorMapService,**不要另写一套渲染**(否则又会出现两张图不一致)。 +- 对话框结构:左侧「异常判定规则」(阈值模式 数值/百分位、最小点数、异常类型)+ 右侧统计信息(最大/最小/均值/中位数)+ 图(同主图)+ 自动标注结果列表 + 底部(取消/执行自动标注/确认保存)。 +- 因为是普通 QWidget(QwtPlot 而非 VTK 窗口),嵌进对话框无任何 OpenGL 上下文问题,开关对话框不会闪烁/泄漏。 + +--- + +## 9. 实施顺序(建议分步验收,避免再次大返工) + +> 每一步做完就和原版对照截图验收,通过再进入下一步。不要一次性全做完再看。 + +1. **搭三层骨架**:DatasetDetailPanel + 两个页签(下划线样式)+ 下方(异常列表/描述)。先不画图,验证 UI 结构对齐(治 #6/#7/#8)。 +2. **QwtPlot 接入 + 交互**:空 QwtPlot,配好固定坐标轴 + Magnifier/Panner,验证"拖动只动数据、轴值跟随、不花屏、纵横比对"(治 #3/#4/#9)。 +3. **ColorBar 独立**:加 ColorBarWidget 固定在下方,验证缩放时色阶条不动、不与轴重叠(治 #1)。 +4. **色阶服务 + 抓原版色值**:实现 ColorMapService,从原版抓真实色值与断点,连续对数映射(治 #2 的基础)。 +5. **散点图**:原数据页用 ScatterPlotItem 连续着色,对照原版配色(治 #2)。 +6. **等值线图**:ContourEngine(VTK 算多边形)+ ContourPlotItem 绘制填充 + 等值线 + 标注(治 #2/#5)。 +7. **工具条联动**:显示异常/等值线/提示、简化容差滑块、白化、滤波接通。 +8. **自动标注对话框**:复用图表组件 + 规则面板 + 统计 + 结果。 +9. **整体对照验收**:原数据、网格数据分别与原版并排截图,核对配色/布局/交互/标注/纵横比。 + +--- + +## 10. 验收标准(写清楚,避免预期错位) + +**通过标准 = 视觉等价 + 交互一致**: + +- [ ] 配色与原版视觉一致(同一色阶、连续插值、对数分布) +- [ ] 坐标轴固定,拖动/缩放只动数据区,轴刻度值跟随 +- [ ] 色阶条固定在轴下方,不随图缩放,不与坐标轴重叠 +- [ ] 等值线数值标注显示,贴合线方向 +- [ ] 原数据=四象限、网格数据=单象限,缩放/移动行为分别与原版一致 +- [ ] 纵横比/宽扁观感与原版一致 +- [ ] 拖动流畅、无花屏 +- [ ] 页签切换为下划线样式(与数据/文件、异常/属性一致) +- [ ] 工具条开关位于各自页签面板内 +- [ ] 下方含「异常列表 + 描述」两个页签 +- [ ] 自动标注对话框内图与主图完全一致 + +**不作为通过标准**(明确排除,避免无意义返工): + +- ✗ 与 web 端逐像素 diff 相同(抗锯齿/字体/亚像素天生有别,任何原生方案都无法做到,非缺陷)。 + +--- + +## 11. 一句话方向 + +> 不嵌 Chromium。推翻 QGraphicsView,用 **QwtPlot(坐标系/交互/图例)+ VTK 算法(等值线多边形)+ 连续对数色阶(对齐原版)**,三层分离(绘图区 / 固定坐标轴 / 独立色阶条),UI 三处(页签样式/工具条归位/描述页)按原版恢复。验收按"视觉等价 + 交互一致",非字节级。 + +--- + +*本方案针对当前返工,钉死架构与分层,禁止在图表渲染框架上再自由发挥。未覆盖的细节先确认再实现。* diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3c092ba..e7c13fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,6 +80,12 @@ target_sources(geopro_tests PRIVATE render/test_terrain.cpp) target_link_libraries(geopro_tests PRIVATE geopro_render ${VTK_LIBRARIES}) vtk_module_autoinit(TARGETS geopro_tests MODULES ${VTK_LIBRARIES}) +# Qwt 集成冒烟(仅当 qwt 目标存在,即 external/qwt-src 已拉取)。 +if(TARGET qwt) + target_sources(geopro_tests PRIVATE render/test_qwt_smoke.cpp) + target_link_libraries(geopro_tests PRIVATE qwt) +endif() + target_include_directories(geopro_tests PRIVATE ${CMAKE_SOURCE_DIR}/src/app) target_sources(geopro_tests PRIVATE app/test_chart_strategy_registry.cpp) diff --git a/tests/render/test_qwt_smoke.cpp b/tests/render/test_qwt_smoke.cpp new file mode 100644 index 0000000..8dcf0c2 --- /dev/null +++ b/tests/render/test_qwt_smoke.cpp @@ -0,0 +1,10 @@ +#include + +#include + +// 冒烟:验证项目能编译 Qwt 头文件并链接 Qwt 静态库(QwtText 为值类型,无需 QApplication)。 +// 保障 Qwt 集成(cmake/qwt.cmake + 官方 Qt6)持续可用,不回归。 +TEST(QwtSmoke, LinksAgainstQwt) { + QwtText t(QStringLiteral("hello")); + EXPECT_EQ(t.text(), QStringLiteral("hello")); +}