【Qt开发流程】之打印文档

描述

Qt为打印提供了广泛的跨平台支持。使用每个平台上的打印系统,Qt应用程序可以打印到连接的打印机上,也可以通过网络打印到远程打印机上。Qt的打印系统还支持PDF文件生成,为基本报表生成工具提供了基础。

支持打印的类

下面的类支持选择和设置打印机和打印输出。

作用
QAbstractPrintDialog用于配置打印机的打印对话框的基本实现
QPageSetupDialog配置对话框,用于打印机上与页面相关的选项
QPrintDialog用于指定打印机配置的对话框
QPrintPreviewDialog用于预览和配置打印机输出的页面布局的对话框
QPrintEngine定义QPrinter与给定打印子系统交互的接口
QPrinter在打印机上作画的装置
QPrinterInfo提供对现有打印机信息的访问
QPrintPreviewWidget用于预览打印机输出的页面布局的小部件

打印设备

在Qt中,打印机由QPrinter表示,QPrinter是一个绘图设备,它提供了特定于打印的功能,例如支持多页和双面输出。因此,打印需要使用QPainter在一系列页面上进行绘制,就像在自定义小部件或图像上进行绘制一样。

创建一个QPrinter

虽然QPrinter对象可以在不需要用户输入的情况下构造和设置,但打印通常是作为用户请求的结果执行的;例如,当用户选择File|Print…菜单项。在这种情况下,一个新构造的QPrinter对象被提供给QPrintDialog,允许用户指定要使用的打印机、纸张大小和其他打印属性。

          QPrinter printer;QPrintDialog dialog(&printer, this);dialog.setWindowTitle(tr("Print Document"));if (editor->textCursor().hasSelection())dialog.addEnabledOption(QAbstractPrintDialog::PrintSelection);if (dialog.exec() != QDialog::Accepted) {return;}

在将QPrinter提供给打印对话框之前,也可以通过修改它来设置某些默认属性。例如,生成批量报告用于打印的应用程序可以将QPrinter设置为默认情况下写入本地文件,而不是写入打印机。

打印页

一旦构造并设置了QPrinter对象,就可以使用QPainter对其执行绘画操作。可以通过以下方式来建构和设置一个画家:

      QPrinter printer(QPrinter::HighResolution);printer.setOutputFileName("print.ps");QPainter painter;painter.begin(&printer);for (int page = 0; page < numberOfPages; ++page) {// Use the painter to draw on the page.if (page != lastPage)printer.newPage();}painter.end();

由于QPrinter从空白页开始,只需要在绘制每个页面后调用newPage()函数,最后一页除外。
当调用end()时,文档被发送到打印机或写入到本地文件。

坐标系统

QPrinter提供的函数可用于获取有关纸张尺寸(纸张矩形)和可打印区域尺寸(页面矩形)的信息。这些是在逻辑设备坐标中给出的,可能与设备本身使用的物理坐标不同,这表明打印机能够以比用户显示器更高的分辨率呈现文本和图形。
虽然不需要自己处理逻辑和物理坐标之间的转换,但仍然需要将转换应用于绘制操作,因为用于在屏幕上绘制的像素测量值对于典型打印机的高分辨率来说通常太小。

  • 打印机和画家坐标系统

paperRect()和pag竖立()函数提供有关用于打印的纸张的大小和可以在其上绘制的区域的信息。
pag竖立()返回的矩形通常位于paperRect()返回的矩形内。当使用QPainter和QPrinter作为底层绘画设备时,不需要考虑这些区域的位置和大小;绘制器坐标系统的原点将与页面矩形的左上角重合,绘制操作将被剪切到页面可绘制部分的边界上。

在这里插入图片描述
绘制文本时,绘制系统会自动使用正确的设备度量,但是,如果需要使用从字体度量获得的信息来定位文本,则需要确保在构造QFontMetrics和QFontMetricsF对象时指定了打印设备,或者确保使用的每个QFont都是使用接受QPaintDevice参数的构造函数的形式构造的。

打印控件

要打印小部件,可以使用QWidget::render()函数。如前所述,打印机的分辨率通常高于屏幕分辨率,因此必须缩放打印对象。可能还想在页面上定位小部件。下面的代码示例显示了这可能是什么样子。

          QPainter painter;painter.begin(&printer);double xscale = printer.pageRect().width()/double(myWidget->width());double yscale = printer.pageRect().height()/double(myWidget->height());double scale = qMin(xscale, yscale);painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,printer.paperRect().y() + printer.pageRect().height()/2);painter.scale(scale, scale);painter.translate(-width()/2, -height()/2);myWidget->render(&painter);

这将使小部件在页面上居中并缩放,使其适合页面。

从复杂小部件打印

某些小部件,如QTextEdit和QGraphicsView,显示丰富的内容,这些内容通常由其他类的实例管理,如QTextDocument和QGraphicsScene。因此,通常是这些内容处理类通过可用于执行完整任务的函数或通过接受现有QPainter对象的函数提供打印功能。一些小部件提供了方便的函数来公开底层打印特性,从而避免了为了调用单个函数而获取内容处理程序的需要。
下表显示了哪个类和函数负责从选择的不同小部件中进行打印。对于不直接公开打印功能的小部件,可以通过相应小部件API中的函数获得包含该功能的内容处理类。
在这里插入图片描述
QTextEdit需要QPrinter而不是QPainter,因为它使用有关配置页面尺寸的信息,以便在打印文档中最合适的位置插入分页符。

示例

UI:
在这里插入图片描述
需要在.pro中添加:

QT += printsupport

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>class QPrinter;namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();public slots:void doPrint();void doPrintPreview();void printPreview(QPrinter *painter);void createPDF();private slots:void on_action_print_triggered();void on_action_printPreview_triggered();void on_action_create_triggered();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QPrinter>
#include <QtPrintSupport/QPrintDialog>
#include <QtPrintSupport/QPrintPreviewDialog>
#include <QFileDialog>
#include <QFileInfo>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::doPrint()
{QPrinter printer;QPrintDialog dlg(&printer, this);if(ui->textEdit->textCursor().hasSelection()){dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);}if(QDialog::Accepted == dlg.exec()){ui->textEdit->print(&printer);}
}void MainWindow::doPrintPreview()
{QPrinter printer;QPrintPreviewDialog preview(&printer, this);connect(&preview, &QPrintPreviewDialog::paintRequested, this, &MainWindow::printPreview);preview.exec();
}void MainWindow::printPreview(QPrinter *printer)
{ui->textEdit->print(printer);
}void MainWindow::createPDF()
{QString strFileName = QFileDialog::getSaveFileName(this, "exportPDF", "./", "*.pdf");if(!strFileName.isEmpty()){if(QFileInfo(strFileName).suffix().isEmpty()){strFileName.append(".pdf");}QPrinter printer;printer.setOutputFormat(QPrinter::PdfFormat);printer.setOutputFileName(strFileName);ui->textEdit->print(&printer);}
}void MainWindow::on_action_print_triggered()
{doPrint();
}void MainWindow::on_action_printPreview_triggered()
{doPrintPreview();
}void MainWindow::on_action_create_triggered()
{createPDF();
}

结果截图

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【经验分享】openGauss 客户端(Data Studio / DBeaver)连接方式

前言 本篇介绍了openGauss常用的客户端连接工具Data Studio和DBeaver 01 客户端工具 openGauss部署之后&#xff0c;在服务器上提供了在命令行下运行的数据库连接工具gsql。此工具除了具备操作数据库的基本功能&#xff0c;还提供了若干高级特性&#xff0c;便于用户使用。…

数据结构---堆

1.堆的概念及结构 堆的性质&#xff1a; 堆中某个节点的值总是不大于或不小于其父节点的值堆总是一棵完全二叉树 2.举例说明 堆一般是把数组数据看做是一棵完全二叉树 小堆要求&#xff1a;任意一个父亲<孩子大堆要求&#xff1a;任意一个父亲>孩子 比如&#xff1…

Zookeeper+Kafka集群

注&#xff1a;本章使用的Kafka为2.7.0版本 Zookeeper概述 1.Zookeeper定义 Zookeeper是一个开源的分布式的&#xff0c;为分布式框架提供协调服务的Apache项目。 2.Zookeeper工作机制 Zookeeper从设计模式角度来理解&#xff1a;是一个基于观察者模式设计的分布式服务管理…

MAMP Pro v6.8.1(PHP/MySQL开发环境)

MAMP Pro是一款专为Mac用户设计的全功能本地服务器软件&#xff0c;可以将电脑变成一个完整的Web开发环境。无论个人开发者、网站管理员还是团队协作&#xff0c;MAMP Pro都提供了强大的工具和便捷的管理方式&#xff0c;能够更加高效地构建和测试网站。 MAMP Pro的基本功能包括…

数据库的多表查询(MYSQL)表表联立

根据以上三张表格&#xff0c;对三张表格进行不同的联立&#xff0c;查询并显示符合条件的内容。 1. 查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数。 mysql> SELECT d.deptno AS 部门编号, d.dname as 部门名称, d.loc as 部门位置, COUNT(e.emp…

长沙电信大楼火灾调查报告发布:系烟头引发。FIS来护航安全

近日&#xff0c;长沙电信大楼的火灾调查报告引起广泛关注。调查发现&#xff0c;火灾是由未熄灭的烟头引发&#xff0c;烟头点燃了室外平台的易燃物&#xff0c;迅速蔓延至整个建筑。这起悲剧再次提醒我们&#xff0c;小小的疏忽可能酿成大灾难。但如果我们能及时发现并处理这…

大模型的RPA应用 | 代理流程自动化(APA),开启智能自动化新纪元

随着技术创新的持续推进&#xff0c;自动化技术已经变得至关重要&#xff0c;成为驱动企业和社会向前发展的核心动力。在自动化的里程碑中&#xff0c;机器人流程自动化&#xff08;RPA&#xff09;已经有效地将简单、重复且规则性的任务自动化。可是随着对处理更为复杂、多变且…

P29 C++箭头运算符以及它对于结构体与类的指针关系

本期的主要内容是箭头运算符以及它对于结构体与类的指针可以做什么&#xff0c;最后实现我们自己的运算符重载。 01 为什么要使用运算符重载 从开发的角度而言&#xff0c;运算符重载的存在是为了提高开发效率&#xff0c;增加代码的可复用性&#xff0c;很多时候简化了代码。…

XIAO ESP32S3之模型部署

参考资料&#xff1a; sipeed AI教程&#xff1a;AI 指南 - Sipeed Wiki TinyMX:https://github.com/sipeed/TinyMaix EdgeLab:https://edgelab.readthedocs.io/zh-cn/latest/ sscma-example-esp32:GitHub - Seeed-Studio/sscma-example-esp32: Example of SenseCraft Mode…

【开源】基于Vue+SpringBoot的高校宿舍调配管理系统

项目编号&#xff1a; S 051 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S051&#xff0c;文末获取源码。} 项目编号&#xff1a;S051&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能需求2.1 学生端2.2 宿管2.3 老师端 三、系统…

Go语言与Java:一场编程语言之争

近年来&#xff0c;Go语言&#xff08;简称Go&#xff09;的崛起引发了对编程语言选择的深刻思考。Java&#xff0c;作为一门经典的编程语言&#xff0c;长期以来一直是企业级应用的首选。 然而&#xff0c;随着Go的逐渐成熟和广泛应用&#xff0c;人们开始重新评估Java是否仍…

Android系统源码中添加可编译运行执行程序,java

文章目录 Android系统源码中添加可编译运行执行程序&#xff0c;java1.Android设备中执行编译运行java代码2.编译执行jar包 Android系统源码中添加可编译运行执行程序&#xff0c;java 1.Android设备中执行编译运行java代码 新建一个文件夹&#xff0c;以及Java类的包路径 测…

linux 消息队列apache-activemq服务的安装

1.下载 官网下载地址&#xff1a;https://activemq.apache.org/ 操作如下&#xff1a; 2. 解压 执行&#xff1a;tar -zxvf apache-activemq-5.18.3-bin.tar.gz -C /user/ 3. 进入目录 执行&#xff1a;cd /user/apache-activemq-5.18.3 4.修改配置文件 执行&#xff1…

深度学习(二):pytorch基础知识

pytorch基础知识 张量&#xff08;Tensors&#xff09;自动微分&#xff08;Autograd&#xff09;模型构建数据加载和处理损失函数优化器&#xff08;Optimizers&#xff09;训练循环GPU加速模型保存和加载部署和推理PyTorch生态系统学习率调度&#xff08;Learning Rate Sched…

Java研学-IO流(二)

三 流资源类结构 1 Java中的流资源可操作文件中的数据 – IO流 ① 将数据写入到指定的文件中 ② 将数据从指定的文件中读出 2 分类 – 四大基流,八大子流 按照流向分:输入流和输出流 按照操作数据源的类型分: ① 字符流 Reader – 字符输入流 – InputStream – 基流 FileR…

基于单片机的电子密码锁设计

1&#xff0e;设计任务 利用AT89C51单片机为核心控制元件,设计一个简易的电子密码锁&#xff0c;可设置四位密码&#xff0c;输入错误三次&#xff0c;报警灯亮起&#xff08;红灯亮起&#xff09;&#xff0c;输入正确&#xff0c;绿灯闪烁三次。可通过LCD显示屏查看密码&…

LeetCode200. Number of Islands——DFS

文章目录 一、题目二、题解 一、题目 Given an m x n 2D binary grid grid which represents a map of 1’s (land) and 0’s (water), return the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertic…

智能生活:人工智能如何改变我们的日常

在科技迅猛发展的今天&#xff0c;人工智能&#xff08;AI&#xff09;已成为我们生活中的一部分。这项技术不仅仅是冷冰冰的代码和算法&#xff0c;而是一个全新的帮手&#xff0c;为我们的日常生活带来了前所未有的便利和智慧。本文旨在探讨人工智能如何影响我们的生活&#…

堆栈_栈实现队列

//请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; // // 实现 MyQueue 类&#xff1a; // // // void push(int x) 将元素 x 推到队列的末尾 // int pop() 从队列的开头移除并返回元素…

Linux常用命令----history命令

文章目录 在Linux中&#xff0c;history命令是一个极其有用的工具&#xff0c;它可以帮助用户查看和管理之前执行过的命令历史。这个功能对于快速查找和重用之前的命令特别有帮助。下面&#xff0c;我们将通过一些实例&#xff0c;详细介绍history命令的使用方法。 1. 基本使用…