前面的四篇实战文章中,我们已经完成了:
- 第一篇:Qt 项目架构设计
- 第二篇:TCP 通信与自定义文本协议
- 第三篇:雷达目标模型与坐标转换
- 第四篇:QPainter 绘制 PPI 雷达界面
但是这些模块目前还是相对独立的。
一个完整的雷达模拟器,需要将:
控制命令、雷达数据、界面显示
真正连接起来。
这一篇将把 RadarSimulator 的核心数据流程进行完整整合。
1. RadarSimulator 整体数据流程
一个完整的数据链路如下:

图1 RadarSimulator 整体数据流架构
其中:
- TCP Client 负责发送控制命令
- RadarServer 负责 TCP 通信和协议解析
- RadarSimulation 负责生成和更新雷达数据
- RadarWidget 负责将数据转换为可视化界面
这种分层设计,可以让网络通信、数据处理和界面绘制相互独立。
2. TCP 命令如何影响雷达状态
在第二篇文章中,我们实现了基于 TCP 的自定义文本协议。
客户端发送的控制命令,会首先进入 RadarServer。 经过协议解析后,进一步改变雷达系统当前状态。
例如客户端发送:
START_SCAN
RadarServer 接收到命令后,会经过以下流程:

图2 TCP命令到雷达状态的处理流程
RadarServer 的职责并不是绘制界面,而是:
- 接收客户端请求
- 解析协议
- 修改雷达状态
- 返回处理结果
这样可以避免网络通信代码和 Qt 界面代码混在一起。
3. 雷达数据如何传递到 Qt 界面
第三篇文章中,我们介绍了雷达目标模型以及坐标转换过程。
雷达系统内部保存的并不是屏幕坐标,而是距离、方位角等雷达参数。
雷达目标通常包含:
- 距离 Range
- 方位角 Azimuth
- 速度 Speed
例如:
struct Target
{
double range;
double azimuth;
double speed;
};
RadarSimulation 负责维护这些数据。
RadarWidget 不负责产生数据,而是读取当前状态。
整体关系:

图3 雷达数据与界面显示关系
这种设计符合 Qt 中常见的:
数据模型与界面显示分离
原则。
4. 雷达坐标到屏幕坐标的转换
RadarSimulation 保存的是雷达坐标。
例如:
- 目标距离
- 目标方位角
但是 Qt 界面使用的是屏幕像素坐标。
因此需要进行坐标转换。
首先计算目标在 PPI 中的显示半径:
r
s
=
r
a
n
g
e
m
a
x
R
a
n
g
e
×
R
r_s= \\frac{range}{maxRange}\\times R
rs=maxRangerange×R
其中:
-
r
s
r_s
rs 为屏幕显示半径 -
r
a
n
g
e
range
range 为目标实际距离 -
m
a
x
R
a
n
g
e
maxRange
maxRange 为最大显示距离 -
R
R
R 为 PPI 圆盘半径
然后计算目标屏幕坐标:
x
=
c
x
+
r
s
sin
(
θ
)
x=c_x+r_s\\sin(\\theta)
x=cx+rssin(θ)
y
=
c
y
−
r
s
cos
(
θ
)
y=c_y-r_s\\cos(\\theta)
y=cy−rscos(θ)
其中:
-
(
c
x
,
c
y
)
(c_x,c_y)
(cx,cy) 为雷达中心坐标 -
θ
\\theta
θ 为目标方位角
经过转换以后,RadarWidget 就可以直接使用 QPainter 绘制目标。
5. Qt 动态刷新机制
雷达界面不是静态图片。
扫描角度、目标位置以及历史航迹都会不断变化。
因此需要周期刷新。
整体流程:

图4 Qt雷达界面动态刷新流程
其中:
update() 并不会立即执行绘制。
Qt 会将重绘请求加入事件队列,并在事件循环中触发
paintEvent()
完成界面刷新。
6. paintEvent 只负责绘制
第四篇文章中,我们介绍了使用 QPainter 绘制 PPI 雷达界面的过程。
其中一个重要原则: paintEvent() 只负责绘制,不负责业务逻辑。
如果将数据更新逻辑放入paintEvent(),会导致:
- 数据更新依赖界面刷新
- 绘制频率影响业务逻辑
- 程序难以测试和维护
正确方式:

图5 数据更新与界面绘制分离
数据层负责产生和维护状态。
界面层只负责读取数据并显示。
这样即使界面暂时停止刷新,雷达数据仍然保持正确状态。
7. TCP、雷达数据与 PPI 的完整闭环
经过整合以后,RadarSimulator 的完整流程如下:

图6 RadarSimulator完整运行闭环
最终实现:
- TCP 控制雷达状态
- 雷达数据实时更新
- PPI 界面动态显示
- 目标和历史航迹同步变化
8. 最终运行效果
经过前面的整合以后,RadarSimulator 已经能够把网络命令、雷达数据和 Qt 图形界面连接起来,形成一个完整的运行系统。
下面展示 RadarSimulator 的实际运行效果。

图7 RadarSimulator实际运行效果
从最终效果来看,项目已经具备了以下几个核心能力:
- 可以通过 TCP 命令控制雷达运行状态
- 可以维护并更新目标数据
- 可以将雷达坐标转换为屏幕坐标
- 可以在 PPI 界面中动态绘制扫描波束、目标和历史航迹
这也意味着前面介绍的几个关键模块,已经真正形成了完整联动。
总结
到这里,RadarSimulator 已经完成了从 TCP 通信、雷达数据处理、坐标转换到 PPI 图形显示的完整链路整合。
前面的模块不再是独立功能,而是通过数据流连接起来,形成了一个完整运行的 Qt 雷达模拟系统。
后续如果继续扩展,可以围绕当前结构逐步完善:
- 更复杂的目标运动轨迹模拟
- 多目标管理与显示
- 雷达参数配置功能
- 数据记录与回放
- 更完善的测试与工程化设计
项目源码
RadarSimulator 完整源码已经开源:
- Gitee仓库
- GitHub仓库
项目包含 Qt6 界面、TCP通信、自定义协议、雷达数据模拟以及 PPI 绘制等模块。
欢迎交流学习。


