Qt无法直接显示DWG/DXF因无内置CAD内核,需通过SDK或转换工具解析为SVG/PDF等中间格式,再用QGraphicsView渲染并处理缩放、拾取、图层等交互。

Qt 本身不提供 CAD 内核,开发“CAD 看图软件”不是加载一张 PNG 那么简单——它必须能解析 DWG/DXF 等格式的几何语义(比如一条 LINE 实体带起点、终点、图层、线型),而 Qt 的 QImage 或 QPixmap 只能显示栅格图像,无法缩放不失真、无法拾取实体、无法按图层控制显隐。
为什么不能直接用 QLabel + QPixmap 显示 DWG?
因为 DWG 不是图片,是二进制数据库。你双击打开的 DWG 文件,背后是中望 CAD、AutoCAD 这类软件用私有或部分公开的 API 解析出图形实体,再调用绘图引擎渲染成像素。Qt 没有内置 DWG 解析器,QPixmap::load() 对 .dwg 文件返回 false,且不会报具体错误,只会静默失败。
- 常见错误现象:
QPixmap::load("test.dwg")返回false,label->setPixmap(pix)后界面空白,控制台无提示 - 误操作路径:把 DWG 当普通图片拖进资源文件(
.qrc),编译后仍无法加载——.qrc只打包二进制,不触发解析 - 性能陷阱:有人尝试用开源库 libdxfrw 读 DXF,再用
QPainter逐条画线,结果 10MB DXF 渲染卡顿严重,因未做视图裁剪和 LOD(细节分级)
可行路径只有两条:对接 CAD 内核 or 转换为中间格式
真实项目中几乎都选后者:把 DWG/DXF 转成 Qt 能高效处理的结构化数据或图像流。
- 推荐方案:用中望 CAD SDK(免费)启动后台进程或 DLL,调用其
AcDbDatabase::readDwgFile()解析,导出为自定义 JSON 或 SVG 路径数组,Qt 主线程只负责渲染这些矢量指令 - 轻量替代:用
ODA File Converter(Open Design Alliance)命令行工具,把 DWG 批量转为 PDF 或 SVG,再用QSvgRenderer或QPdfDocument(Qt 6.5+)加载——注意 PDF 渲染需启用QtPdf模块 - 避坑提醒:不要用系统自带的“打印为 PDF”方式转换,会丢失图层、文字可编辑性,且比例常错乱
核心渲染必须绕过 QLabel,改用 QGraphicsView
QLabel::setPixmap() 适合静态图,但 CAD 看图要平移、缩放、框选、高亮实体——这些交互在 QGraphicsView 里是开箱即用的。
- 必须继承
QGraphicsView,重写wheelEvent()实现滚轮缩放,mousePressEvent()记录拖拽起点 - 所有图形实体(线、圆、文字)应封装为
QGraphicsItem子类,而非画在QPainter上——否则无法响应itemAt()拾取 - 避免在
paintEvent()里反复drawLine():每帧重绘千条线会掉帧;正确做法是把几何数据存在QGraphicsScene,让 Qt 自动批处理绘制
图层、颜色、线型这些 CAD 属性怎么映射?
不能靠猜测。DWG 中的 ACI color(1–255 编号色)必须查表转成 QColor,线型(CONTINUOUS、DASHED)要对应 QPen::setDashPattern(),否则看起来就是一堆黑线。
- 关键参数:从 DWG 解析出的
AcCmColor对象,调用colorIndex()获取 ACI 值,查 Qt 内置的 ACI-to-RGB 表(Qt 本身不提供,需自己建) - 线宽陷阱:DWG 的
lineweight单位是毫米,Qt 的QPen::setWidthF()是像素,需结合当前缩放系数换算,否则放大后线变细成发丝 - 文字渲染:DXF 的 TEXT 实体含
height和textStyle,不能直接用QGraphicsTextItem,因其不支持 SHX 字体;稳妥做法是转成轮廓(QPainterPath)再绘制
最易被忽略的是坐标系单位与 DPI 适配:CAD 文件用毫米或英寸建模,Qt 默认以像素为单位,QGraphicsView::scale() 放大 2 倍时,若不重新计算文字高度和线宽,标注数字会糊成一片。这问题在高分屏(如 200% 缩放)下更致命,必须用 devicePixelRatio() 校正。











