1. 从零开始:理解Qt打印的核心QPrinter
如果你在开发一个桌面应用,比如学生信息管理系统、库存管理软件或者报表工具,那么“打印”功能几乎是一个绕不开的需求。用户总需要把屏幕上的数据变成一张实实在在的纸,或者一份可以存档的PDF文件。在Qt的世界里,实现这个功能的核心,就是 QPrinter 类。
我刚开始接触Qt打印的时候,也犯过迷糊,觉得这玩意儿是不是特别复杂。但实际用下来发现,QPrinter本质上就是一个特殊的“画布”。你可以把它想象成一张虚拟的纸,而我们平时在屏幕上用QPainter画图、写字,现在只需要把QPainter关联到这个“虚拟的纸”上,画什么,打印机就输出什么。这个设计非常巧妙,它把复杂的打印机驱动、页面描述语言(比如PostScript)都封装了起来,让我们开发者可以用一套熟悉的绘图API来处理打印,大大降低了门槛。
不过,直接上手画虽然自由,但处理复杂的、带格式的文档(比如一个有很多行和列的表格)就比较费劲了。这时候,Qt提供了另一个强大的武器:QTextDocument。它支持用HTML和CSS来定义丰富的文本格式和简单的表格。我们可以先把要打印的内容(比如表格数据)组装成一段HTML代码,然后交给QTextDocument去“渲染”,最后再让QTextDocument把渲染好的内容“画”到QPrinter上。这就像我们先用Word写好一个带表格的文档,然后点击打印一样自然。
所以,一个典型的Qt打印流程通常是这样的:创建QPrinter对象设置纸张、方向 -> 准备内容(用QPainter直接画,或者用QTextDocument加载HTML) -> 调用打印。为了让用户有更好的体验,我们还会用到QPrintDialog(让用户选择打印机和设置参数)和QPrintPreviewDialog(让用户先预览一下效果再打印)。下面,我就带你一步步把这些环节打通,并分享一些我踩过坑才总结出来的实战技巧。
2. 实战第一步:配置你的QPrinter对象
万事开头难,打印的第一步就是正确创建和配置QPrinter。这里有几个关键点,直接影响到打印输出的质量和跨平台表现。
2.1 选择正确的打印机模式(PrinterMode)
创建QPrinter时,第一个重要的选择就是PrinterMode。它主要影响打印的分辨率。
// 方式一:使用屏幕分辨率(默认)
QPrinter printer(QPrinter::ScreenResolution);
// 方式二:使用高分辨率(推荐用于正式打印)
QPrinter printer(QPrinter::HighResolution);
这里有个坑我早期经常踩:QPrinter::ScreenResolution模式虽然方便,但输出质量可能不高。它的原理是把打印机的DPI(每英寸点数)设置成和屏幕一样(比如96 DPI)。这样做的好处是,你在屏幕上用QPainter画一个100像素宽的矩形,打印出来宽度也差不多,所见即所得,调试布局很方便。但缺点是,打印机实际物理精度很高(通常是300, 600甚至1200 DPI),用低分辨率去驱动,打印出来的文字和图形边缘可能会有锯齿,不够清晰。所以,我现在的习惯是:开发调试阶段用ScreenResolution快速验证布局,最终发布时切换到HighResolution保证输出质量。至于那个QPrinter::PrinterResolution,官方文档已经明确标记为“废弃”,就是因为它在不同系统上行为不一致,容易导致跨平台问题,我们直接避开不用就好。
2.2 设置页面属性与输出目标
创建好对象后,我们就要告诉它:你要打到哪里去?打多大的纸?怎么打?
// 1. 设置输出格式:是打到真实的打印机,还是生成PDF文件?
printer.setOutputFormat(QPrinter::NativeFormat); // 使用系统默认打印机驱动
// printer.setOutputFormat(QPrinter::PdfFormat); // 输出为PDF文件
// printer.setOutputFileName("/path/to/output.pdf"); // 指定PDF保存路径
// 2. 设置纸张大小和方向(这是最常用的设置)
printer.setPageSize(QPrinter::A4); // A4纸,还有Letter, Legal, A3等可选
printer.setOrientation(QPrinter::Portrait); // 纵向
// printer.setOrientation(QPrinter::Landscape); // 横向,适合宽表格
// 3. 设置页边距(单位可以是毫米、英寸等)
printer.setPageMargins(15, 15, 15, 15, QPrinter::Millimeter); // 左、上、右、下边距
// 4. 设置打印份数和双面打印
printer.setCopyCount(2); // 打印2份
printer.setDuplex(QPrinter::DuplexAuto); // 自动双面打印(如果打印机支持)
关于页边距,这里有个特别需要注意的地方:setFullPage函数。默认情况下,QPrinter的坐标原点(0,0)位于页面的可打印区域的左上角,而不是物理纸张的左上角。打印机通常会有一个无法打印的边沿(比如进纸辊占用的位置)。如果你调用printer.setFullPage(true);,那么坐标原点就会移到物理纸张的角落,但你需要自己承担内容打印到非打印区域的风险。对于绝大多数表格和文档打印,我建议保持默认的false,这样更安全。
2.3 跨平台兼容性处理
Qt的优势是跨平台,但打印恰恰是平台相关性比较强的部分。为了让你的代码在Windows、macOS和Linux上都能稳定工作,需要注意以下几点:
- 字体嵌入:如果你使用了非系统默认字体,并且希望PDF在任何电脑上打开都能正确显示,就需要开启字体嵌入。
printer.setFontEmbeddingEnabled(true);。但这会增大PDF文件体积。 - 分辨率依赖:在
HighResolution模式下,Windows和macOS会使用打印机驱动报告的真实DPI(如600),而生成PDF时固定为1200 DPI。如果你的绘图代码中使用了


55

被折叠的 条评论
为什么被折叠?



