欢迎光临
我们一直在努力

Qt开发技术:Qt打印系统(二)Qt打印机QPrinter

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/162831636

长沙红胖子Qt·西安(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…

Qt开发专栏:三方库开发技术

上一篇:《Qt开发技术:Qt打印系统(一)打印系统介绍和基础环境Demo》 下一篇:敬请期待…

前言

  先要了解打印机如何简单而全的打印,熟悉QPainter。

Demo演示

  在这里插入图片描述

QPrinter

介绍

  QPrinter类是一种在打印机上绘制的绘制设备。   此设备表示一系列打印输出页面,其使用方式几乎与QWidget和QPixmap等其他绘图设备完全相同。提供了一组附加功能来管理设备特定的功能,如方向和分辨率,并在生成文档时逐步浏览文档中的页面。   在Windows或macOS上直接打印到打印机时,QPrinter使用内置的打印机驱动程序。在X11上,QPrinter使用通用Unix打印系统(CUPS)将PDF输出发送到打印机。作为替代方案,可以使用printProgram()函数指定要使用的命令或实用程序,而不是系统默认值。   注意,在无效打印机上设置纸张尺寸和分辨率等参数是未定义的。在更改任何参数之前,可以使用QPrinter::isValid()来验证这一点。   QPrinter支持许多参数,其中大多数参数可以由最终用户通过打印对话框进行更改。一般来说,QPrinter会将这些函数传递给底层QPrintEngine。   最重要的函数属性参数:

  • setOrientation():QPrinter要使用哪个页面方向。
  • setPaperSize():QPrinter打印机期望的纸张大小。
  • setResolution():QPrinter希望打印机提供的分辨率,单位为每英寸点数(DPI)。每英寸点数,缩写 DPI:指在1 英寸(2.54cm) 长度内,设备能输出 / 识别的点(墨点、打印像素、扫描采样点)数量。数值越大,细节越细腻、清晰度越高。
  • setFullPage():QPrinter您是要处理整页还是只处理打印机可以绘制的部分。
  • setCopyCount():告诉QPrinter应该打印多少份文档。

  许多这些函数只能在实际打印开始前调用(即在调用QPainter::begin()之前)。这通常是有道理的,因为例如,在打印进行到一半时无法更改打印份数。还有一些设置由用户通过打印机对话框指定,应用程序需遵守这些设置。详见QAbstractPrintDialog的文档说明。   当调用QPainter::begin()时,其操作的QPrinter将准备好开始新页面,使QPainter能够立即用于绘制文档的第一页。绘制完第一页后,可通过调用newPage()请求新的空白页面进行绘制,或调用QPainter::end()完成打印。第二页及后续所有页面需在绘制前通过调用newPage()进行准备。   文档的第一页无需在调用newPage()之前绘制。只有当需要在打印文档的开头插入空白页时,才需要在QPainter::begin()之后调用newPage()。同样地,若在文档最后一页绘制完成后调用newPage(),则会在打印文档的末尾追加一个尾随的空白页。   如果要中止打印作业,abort()将尽力停止打印。它可能会取消整个作业或只是部分作业。   由于QPrinter可以打印到任何QPrintEngine子类,因此可以通过子类化QPrintEngine并重新实现其接口来扩展打印支持,以覆盖新型打印子系统。

打印机枚举定义

enum QPrinter::ColorMode:打印机颜色模式

  此枚举类型用于指示QPrinter是否应彩色打印。   在这里插入图片描述

enum QPrinter::DuplexMode:打印单双页面方式

  此枚举用于指示打印是在每张纸的一面还是两面进行(单面打印还是双面打印)。   在这里插入图片描述

enum QPrinter::Orientation:页面布局横向/纵向

  此枚举类型(不要与方向混淆)用于指定每个页面的方向。   在这里插入图片描述

enum QPrinter::OutputFormat:设置打印机输出

  OutputFormat枚举用于描述QPrinter打印时应使用的格式。   在这里插入图片描述

enum QPrinter::PageOrder:打印页面顺序

  多页面打印顺序。   在这里插入图片描述

enum QPrinter::PaperSize,QPagedPaintDevice::PageSize:纸张大小

  重定义枚举QPagedPaintDevice::PageSize。   此枚举类型指定QPrinter应使用的纸张尺寸。QPrinter不检查纸是否可用;它只使用此信息以及QPrinter::Orientation和QPrinter::setFullPage()来确定可打印区域。   在QPagedPaintDevice中可以找到定义的大小(使用setFullPage(true))。**   使用setFullPage(false)(默认值),指标会稍微小一些;多少取决于使用的打印机。   列举常用枚举:在这里插入图片描述   由于历史原因,QPageSize::Executive(上表未列出来)与标准Postscript和Windows Executive大小不同,请改用QPageSize::ExecutionStandard。   Postscript标准大小QPageSize::Folio与Windows DMPAPER_Folio大小不同,如果需要,请使用Postscript标准尺寸QPageSize::FanFoldGermanLegal。

enum QPrinter::PaperSource:纸张来源

  此枚举类型指定要使用的纸张源QPrinter。QPrinter未检查纸张来源是否可用;它只是使用这些信息来尝试设置纸张来源。是否可以设置纸张来源取决于打印机是否具有该特定来源。   在这里插入图片描述

enum QPrinter::PrintRange:打印页面范围

  用于指定打印范围选择选项。   在这里插入图片描述

enum QPrinter::PrinterMode:打印模式

  在这里插入图片描述   注意:在QPrinter设备上渲染文本时,重要的是要意识到,以点为单位指定的文本大小与为设备本身指定的分辨率无关。因此,在将文本与图形组合时,以像素为单位指定字体大小可能很有用,以确保它们的相对大小符合期望。

enum QPrinter::PrinterState:打印机状态

  在这里插入图片描述

enum QPrinter::Unit:距离单位

   在这里插入图片描述   请注意Point和DevicePixel之间的区别。点单位定义为1/72英寸,而DevicePixel单位取决于分辨率,基于打印机上的实际像素或点。

打印机关键函数

QPrinter::setOutputFormat():设置打印机打印还是打印生成pdf

void QPrinter::setOutputFormat(OutputFormat format)

  将此打印机的输出格式设置为格式化。   如果格式与当前设置的值相同,则不会进行任何更改。   在这里插入图片描述

  如果格式为NativeFormat,则printerName将设置为默认打印机。如果没有配置有效的打印机,则不会进行任何更改。如果要使用特定的printerName设置NativeFormat,请使用setPrinterName()。

QPrinter::setOutputFileName():输出pdf时,设置输出pdf文件

void QPrinter::setOutputFileName(const QString &fileName)

QPrinter::outputFileName():pdf模式有文件名,打印为空

  返回输出文件的名称。默认情况下,这是一个空字符串(表示打印机不应打印到文件)。

setPaperSize():设置打印机纸张

void setPaperSize(PaperSize);

setOrientation():设置页面布局

void setOrientation(Orientation);

  在这里插入图片描述

paperRect():返回纸张大小

  以单位返回纸张的矩形;这通常比pageRect()大。

QRectF paperRect(Unit) const;

pageRect():返回页面的大小(不包含边框)

  以单位返回页面的矩形;这通常比paperRect()小,因为页面的边框和纸张之间通常有边距。   注意:查看“入坑二:页边距画框,右和下不对”加深理解,次函数返回的矩形比较特殊。   x和y:实际上是边框之后的左上角对于整个页面的x和y,但是此时这个x和y的位置对应QPainter又是(0,0)。   width和height:实际上边框之后的宽和高度。

newPage():新建一页

bool QPrinter::newPage()

  从QPagedPaintDevice::newPage()重新实现。   告诉打印机弹出当前页面并在新页面上继续打印。如果成功,则返回true;否则返回false。   在非活动的QPrinter对象上调用newPage()总是会失败。   QPainter活动状态:只有满足QPainter::begin(&printer) 已调用、且还未执行 painter.end() 时,QPrinter 才处于活动打印会话状态。   此时打印引擎已初始化,分配页面缓冲区,可以正常调用 newPage() 换页   生命周期:   painter.begin() →绘制页面→printer.newPage()(换页)→ painter.end()

Demo源码

void PrinterManager::testDemo1()
{
QString fileName = QString("%1.pdf").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh_mm_ss"));
// 步骤一:初始化打印设备
QPrinter printer;
// 步骤二:设置打印设备输出
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
// 步骤三:设置打印机纸张
printer.setPaperSize(QPrinter::A4);
// 步骤四:设置纸张布局
printer.setOrientation(QPrinter::Landscape);
// 步骤五:设置打印分辨率300dpi
printer.setResolution(300);
// 步骤六:设置页边距,单位为ms
printer.setPageMargins(15, 15, 15, 15, QPrinter::Millimeter);
// printer.setPageMargins(0, 0, 0, 0, QPrinter::Millimeter);

// 步骤六:绘制设备
{
// 构建一个绘图设备空对象
QPainter painter;
// 开启打印会话,printer进入活动状态

// —–分页:第一页
if(!painter.begin(&printer))
{
LOG << "PDF绘制初始化失败!路径:" << fileName;
return;
}
LOG << "纸张大小: " << printer.paperRect();
LOG << "页面大小(去掉边框):" << printer.pageRect();
LOG << "Millimeter: " << printer.pageRect(QPrinter::Millimeter);
LOG << "Point: " << printer.pageRect(QPrinter::Point);
LOG << "Inch: " << printer.pageRect(QPrinter::Inch);
LOG << "Pica: " << printer.pageRect(QPrinter::Pica);
LOG << "Didot: " << printer.pageRect(QPrinter::Didot);
LOG << "Cicero: " << printer.pageRect(QPrinter::Cicero);
LOG << "DevicePixel: " << printer.pageRect(QPrinter::DevicePixel);

int penWidth = 10;

painter.setPen(QPen(Qt::black, penWidth));
painter.drawRect(0, 0, printer.pageRect().width(), printer.height());
painter.drawText(0, 0, "第一页:横向布局,这里已经是打印不出了,超出我们设置的页边距了");

// —–分页:第二页
printer.setOrientation(QPrinter::Portrait);
printer.newPage();

painter.setPen(QPen(Qt::red, penWidth));
painter.drawRect(0, 0, printer.pageRect().width(), printer.height());
painter.drawText(0, 0, "第四页:纵向布局,这里已经是打印不出了,超出我们设置的页边距了");

// —–分页:第三页
printer.setOrientation(QPrinter::Landscape);
printer.newPage();

painter.setPen(QPen(Qt::green, penWidth));
painter.drawRect(0, 0, printer.pageRect().width(), printer.height());
painter.drawText(0, 0, "第三页:横向布局,这里已经是打印不出了,超出我们设置的页边距了");

// —–分页:第四页
printer.setOrientation(QPrinter::Portrait);
printer.newPage();

painter.setPen(QPen(Qt::blue, penWidth));
painter.drawRect(0, 0, printer.pageRect().width(), printer.height());
painter.drawText(0, 0, "第四页:纵向布局,这里已经是打印不出了,超出我们设置的页边距了");

// 结束绘制会话,写入PDF文件
painter.end();
}
}

工程模板v1.1.0

  在这里插入图片描述

入坑

入坑一:横向页面布局没效果

问题

  应该是纵向,然后横向,实际输出都是纵向   在这里插入图片描述

尝试

  在设置横向之后,再new一次。   在这里插入图片描述   所以是要newPage才生效。   把第一页设置横向,直接设置,然后没有生效:   在这里插入图片描述

  将设置布局横向,纵向放到painter开始打印之前设置:   在这里插入图片描述   在这里插入图片描述

解决

  每次设置布局,newPage之后生效,第一次设置布局,最好直接当做全局。   第一步:设置页面的时候,就直接多显式设置一次页面布局   在这里插入图片描述

  第二步:更换布局时,先更换布局,再newPage   在这里插入图片描述

入坑二:页边距画框,右和下不对

问题

  绘制页边距之外的边框出现错误    在这里插入图片描述

尝试

  获取的时候,没有写单位,不知道默认单位时什么。   在这里插入图片描述

  测试后,默认就是设备像素:   在这里插入图片描述

  在这里插入图片描述

解决

  在这里插入图片描述

  在这里插入图片描述

上一篇:《Qt开发技术:Qt打印系统(一)打印系统介绍和基础环境Demo》 下一篇:敬请期待…

本文章博客地址:https://hpzwl.blog.csdn.net/article/details/162831636

赞(0)
未经允许不得转载:171主机测评 » Qt开发技术:Qt打印系统(二)Qt打印机QPrinter
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址