QT作为一款轻量级的集成开发环境,其设计的目标是使开发人员利用QT这个应用程序框架更加快速及轻易的开发应用程序。要达到此目的,要求QT必须能够跨平台,QT能够在32位及64位的Linux,MAC OS X以及Windows上运行。

现在我们想在项目中加入一项打印功能,即使在不同的操作系统环境下,仍然能有相同的用户体验,在实现中发现QT对打印的支持不是那么友好。我们希望在跨平台的情况下,能打印各种文档,比如用户的简历,发现如果不调用对应操作系统的内核外壳打印函数,这项工作变得异常艰难。我们希望用QT自带的函数库,来实现简单的打印功能,这样就实现了一次编码,多环境使用的目的。

下面我们分别介绍这两种方法。

一、调用内核外壳打印函数

Linux下面相对比较容易,使用lpr –p [printer] [fileName]即可,即如果想把file.cpp文件送到打印机pl则使用lpr –p pl file.cpp即可。

Windows下,我们实现打印既定文件路径的文档时,我们调用windows内核命令执行函数,实现打印功能。具体代码如下:

bool printFile(const QString & filePath)
{
// create a printer
QPrinter printer;
QString printerName = printer.printerName();
// no default printer or no file return false
if( printerName.size() == 0 || filePath.size() == 0)
return false;
QFileInfo fi(filePath);
if(!fi.exists())
return false;
int ret = 0;
ret = (int)ShellExecuteW(NULL,
QString("print").toStdWString().c_str(),
filePath.toStdWString().c_str(),
NULL,
NULL,
SW_HIDE);
// if return number bigger than 31 indicate succ
if (ret > SE_ERR_NOASSOC)
return true;
return false;
}

二、使用QT自定义的类和函数实现打印文件的功能

className function
QAbstractPrintDialog base implementation for print dialogs used to configure printers
QPageSetupDialog configuration dialog for the page-related options on a printer
QPrintDialog Dialog for specifying the printer's configuration
QPrintEngine Defines an interface for how QPrinter interacts with a given printing subsystem
QPrintPreviewDialog Dialog for previewing and configuring page layouts for printer output
QPrintPreviewWidget Widget for previewing page layouts for printer output
QPrinter Paint device that paints on a printer
QPrinterInfo Gives access to information about existing printers

QT中和打印文件相关的类如下所示,它们分别是:

  • 抽象文档打印对话框类,提供配置打印机的打印对话框基本实现;
  • 页面设置对话框类,和打印页面相关参数的配置对话框;
  • 打印对话框类,指定打印机配置的对话框;
  • 打印引擎类,定义了QPrinter类如何与打印子系统交互的接口;
  • 打印预览对话框类,用来预览和配置页面布局的对话框;
  • 打印预览控件类,预览页面布局的控件;
  • 打印机类,指示打印机如何工作。

QT中实现打印的方法

在QT中如果想实现打印,首先,我们需要构造一个打印机类(QPrinter)对象, 其次,使用此对象构造一个打印对话框类(QprinterDialog)对象。如下所示:

QPrinter printer;
QprinterDialog *dialog = new QprintDialog(&printer, this);
dialog->setWindowtitle(tr(“Print Document”));
if(editor->textCursor().hasSelection())
dialog->addEnabledOption(QabstractPrintDialog::PrintSelection);
if (dialog->exec() != QDialog::Accepted)
return;

最后附上在项目中,我们如何利用QT自身类,来实现这个跨平台的打印功能。

首先,在头文件中指定槽函数:

private slots:
void doPrint();
void doPrintPreview();
void printPreview(QPrinter *printer);
void createPdf();
void setUpPage();
具体实现如下:
void MainWindow::doPrint()
{
// 创建打印机对象
QPrinter printer;
// 创建打印对话框
QString printerName = printer.printerName();
if( printerName.size() == 0)
return;
QPrintDialog dlg(&printer, this);
//如果编辑器中有选中区域,则打印选中区域
if (ui->textEdit->textCursor().hasSelection())
dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
// 如果在对话框中按下了打印按钮,则执行打印操作
if (dlg.exec() == QDialog::Accepted)
{
ui->textEdit->print(&printer);
// print the existing document by absoult path
// printFile("D:/myRSM.doc");
}
}
// 打印预览
void MainWindow::doPrintPreview()
{
QPrinter printer;
// 创建打印预览对话框
QPrintPreviewDialog preview(&printer, this);
// 当要生成预览页面时,发射paintRequested()信号
connect(&preview, SIGNAL(paintRequested(QPrinter*)),
this,SLOT(printPreview(QPrinter*)));
preview.exec();
}
void MainWindow::printPreview(QPrinter *printer)
{
ui->textEdit->print(printer);
}
// 生成PDF文件
void MainWindow::createPdf()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("导出PDF文件"), QString(), "*.pdf");
if (!fileName.isEmpty()) {
// 如果文件后缀为空,则默认使用.pdf
if (QFileInfo(fileName).suffix().isEmpty())
fileName.append(".pdf");
QPrinter printer;
// 指定输出格式为pdf
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);
ui->textEdit->print(&printer);
}
}
// 页面设置
void MainWindow::setUpPage()
{
QPrinter printer;
QPageSetupDialog pageSetUpdlg(&printer, this);
if (pageSetUpdlg.exec() == QDialog::Accepted)
{
printer.setOrientation(QPrinter::Landscape);
}
else
{
printer.setOrientation(QPrinter::Portrait);
}
}

以上,仅为摸索QT的一点心得,供大家共同交流实践,不足之处欢迎大家指出。

http://express.ruanko.com/ruanko-express_75/tech-overnight1.html

http://blog.csdn.net/jdh99/article/details/42585987

浅谈QT打印功能实现的更多相关文章

  1. 浅谈 Qt 布局那些事

    Qt 布局那些事是本文介绍的内容,直接进入主题.GridLayout是一个非常强大的布局管理器,它可以实现很多复杂的布局,名字中暗示它将所有控件放置在类似网格的布局中.^__^GridLayout有两 ...

  2. 浅谈Qt事件的路由机制:鼠标事件

    请注意,本文是探讨文章而不是教程,是根据实验和分析得出的结果,可能是错的,因此欢迎别人来探讨和纠正. 这几天对于Qt的事件较为好奇,平时并不怎么常用,一般都是用信号,对于事件的处理,一般都是需要响应键 ...

  3. 浅谈qt 布局器

    在一个颜值当道的今天,无论买衣服,买车还是追星,颜值的高低已经变成了大家最看重的(不管男性女性都一样,千万别和我说你不是):而对于程序猿来说,开发一款软件,不再只注重逻辑和稳定性,美观和用户友好性也是 ...

  4. 我的QT5学习之路(一)——浅谈QT的安装和配置

    一.前言 说到Qt,不能不说到C++,这门伟大的语言.因为其面向对象的编程思想和陡峭的学习曲线,一开始学习起来很是吃力.Qt从QT4开始基本封装了很多C++的工具库和界面库,而且支持跨平台,这是它最大 ...

  5. 浅谈Bootstrap自适应功能在Web开发中的应用

    随着移动端市场的强势崛起,web的开发也变得愈发复杂,对于个体开发者来说,自己开发的网站,在电脑.手机.Pad等上面都要有正常的显示以及良好的用户体验.如果每次都要自己去调整网页去匹配各个不同的客户端 ...

  6. 浅谈关于QT中Webkit内核浏览器

    关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...

  7. Qt浅谈之总结(整理)

    Qt浅谈之总结(整理) 来源 http://blog.csdn.net/taiyang1987912/article/details/32713781 一.简介 QT的一些知识点总结,方便以后查阅. ...

  8. 浅谈测试rhel7新功能时的感受及遇到的问题【转载】

    半夜起来看世界杯,没啥激情,但是又怕错误意大利和英格兰的比赛,就看了rhel7 相关新功能的介绍. rhel7的下载地址: https://access.redhat.com/site/downloa ...

  9. Qt浅谈内存泄露(总结)

    Qt浅谈内存泄露(总结) 来源 http://blog.csdn.net/taiyang1987912/article/details/29271549 一.简介 Qt内存管理机制:Qt 在内部能够维 ...

随机推荐

  1. nginx的日志分析

    1.到NGINX把日志DOWN下来2.用命令cat xxxx.log | egrep '10/Jul/2015:01:[4-5]|2015-07-10 02:0[0-57]'>xxxx2.log ...

  2. 阿里云启用IPV6

    ping过别人的IPv6网址之后,可以确定,局域网是不支持IPv6的.所以要使用隧道技术建立两台机器之间的IPv6连接 1.发现测试用服务器上没有IPv6地址.所以测试服务器的内核应该是没有IPv6模 ...

  3. 不重启修改'log_slave_updates'变量

    Variable 'log_slave_updates' is a read only variable 不重启修改mysql变量 执行复制的时候遇到的问题 mysql> show variab ...

  4. 开发需求:每个表dump出部分数据

    mysqldump 每张数据表统一导出的N个记录数 需求: 在开发过程中,需要将生产的数据导出到本地开发环境,希望可以每个表都导出部分数据.由于生产数据表都是上千万或亿级别,直接从服务器导出数据会影响 ...

  5. Spark分析之SparkContext启动过程分析

    SparkContext作为整个Spark的入口,不管是spark.sparkstreaming.spark sql都需要首先创建一个SparkContext对象,然后基于这个SparkContext ...

  6. 《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #18 向ext4转换

    HACK #18 向ext4转换 ext4可以与ext2/ext3在后台进行互换.这里将介绍从ext2/ext3转换的方法以及转换时的注意事项.转换有两种方法可以将ext2/ext3的磁盘映像作为ex ...

  7. 常用模块:os模块,logging模块等

    一    os模块 那么作为一个常用模块,os模块是与操作系统交互的一个模块. 那么os模块中我们常用的一般有以下几种: os.listdir('dirname') 以列表的形式列出指定目录下的所有文 ...

  8. pomelo RPC调用时新增字段缺失

    接触pomelo开发一个月,正式开始参与项目开发有10天,遇到很多细节的坑,今天讲讲标题:后端服务器节点之间的rpc调用过程中,返回的数据中新增字段缺失问题. 先讲结果:原因是该rpc调用已经采用了p ...

  9. SignalR (一)

    关于SignalR 因近期要在项目中使用 SignalR 来开发实时web 程序,可在这之前,对SignalR 的了解并不是很多,甚至不知道 SignalR 到底是用来干什么的,可是在经过这段时间的学 ...

  10. NPOI操作word文档1

    1.首先进行XWPFDocument类的实例化,该类的实例对应一个word文档 XWPFDocument MyDoc = new XWPFDocument(); 2.设置页面的大小 CT_SectPr ...