Qt中的打印操作
Qt中对打印的支持是有一个独立的printsupport模块来完成的,所以,要想在程序中使用Qt的打印功能,必须先在pro文件中添加下面这句代码:
QT += printsupport
在这个模块中,提供了八个类来支持打印功能。我们来简单的看几个与打印有直接关系的几个类:
QPageSetupDialog:该类可以用来对打印页面进行一些相关的配置,如页面方向,边距等。
QPrintDialog:该类就代表我们常见的打印对话框。
QPrintPreviewDialog:该类代表打印预览对话框。可以在此对话框中看到我们对页面的设置效果。
QPrinter:可以简单的理解为用于打印的绘图设备。
QPrinterInfo:可以使用该类来获得当前电脑上所连接的可用的打印设备的信息。
下面,我们通过实例来实际了解一下这几个类的使用。
新建一个GUI程序,往界面上拖入一个列表框和4个按钮。效果如下:
下面,我们要完成的功能是,点击“PrinterInfo”按钮,将当前电脑可用的所有打印设备的信息加载到文本框中,然后,再将这些信息打印出来。
先来看“PrinterInfo”按钮的功能代码:
//Printer Info
void Widget::on_printerinfo_clicked()
{
QString info;
list = QPrinterInfo::availablePrinters();
for(const QPrinterInfo& printerInfo : list)
{
info = "defaultDuplexMode: ";
switch (printerInfo.defaultDuplexMode())
{
case QPrinter::DuplexNone:
info += "DuplexNone";
break;
case QPrinter::DuplexAuto:
info += "DuplexAuto";
break;
case QPrinter::DuplexLongSide:
info += "DuplexLongSide";
break;
case QPrinter::DuplexShortSide:
info += "DuplexShortSide";
break;
}
ui->listWidget->addItem(info);
info = "defaultPageSize: ";
info += printerInfo.defaultPageSize().name();
ui->listWidget->addItem(info);
info = "description: ";
info += printerInfo.description();
ui->listWidget->addItem(info);
info = "isDefault: ";
info += printerInfo.isDefault() ? "true" : "false";
ui->listWidget->addItem(info);
info = "isRemote: ";
info += printerInfo.isRemote() ? "true" : "false";
ui->listWidget->addItem(info);
info = "location: " + printerInfo.location();
ui->listWidget->addItem(info);
info = "makeAndModel: " + printerInfo.makeAndModel();
ui->listWidget->addItem(info);
info = "maximumPhysicalPageSize: " + printerInfo.maximumPhysicalPageSize().name();
ui->listWidget->addItem(info);
info = "minimumPhysicalPageSize: " + printerInfo.minimumPhysicalPageSize().name();
ui->listWidget->addItem(info);
info = "printerName: " + printerInfo.printerName();
ui->listWidget->addItem(info);
info = "state: ";
switch(printerInfo.state())
{
case QPrinter::Idle:
info += "Idle";
break;
case QPrinter::Active:
info += "Active";
break;
case QPrinter::Aborted:
info += "Aborted";
break;
case QPrinter::Error:
info += "Error";
break;
}
ui->listWidget->addItem(info);
info = "supportedDuplexModes: ";
for(QPrinter::DuplexMode mode : printerInfo.supportedDuplexModes())
{
switch (mode)
{
case QPrinter::DuplexNone:
info += "DuplexNone";
break;
case QPrinter::DuplexAuto:
info += "DuplexAuto";
break;
case QPrinter::DuplexLongSide:
info += "DuplexLongSide";
break;
case QPrinter::DuplexShortSide:
info += "DuplexShortSide";
break;
}
}
ui->listWidget->addItem(info);
info = "supportedPageSizes: ";
for(QPageSize ps : printerInfo.supportedPageSizes())
{
info += ps.name();
}
ui->listWidget->addItem(info);
info = "supportedResolutions: ";
for(int resolution : printerInfo.supportedResolutions())
{
info += QString::number(resolution);
}
ui->listWidget->addItem(info);
info = "supportsCustomPageSizes: ";
info += printerInfo.supportsCustomPageSizes() ? "true" : false;
ui->listWidget->addItem(info);
ui->listWidget->addItem("");
}
}
其中,QPrinterInfo类的详细信息,大家可以参看Qt帮助文档。此处,我们使用该类的静态方法availablePrinters()来获取到所有可用的打印设备,每一个打印设备由一个QPrinterInfo类来表示,然后我们将每一个QPrinterInfo的详细信息插入到QListWidget中。每一个QPrinterInfo的信息以一个空行分隔。下面,也用这个空行来完成分页。
“PageSetupDialog”按钮的实现代码如下:
//页面设置对话框
void Widget::on_pagesetupdlg_clicked()
{
QPrinter printer(QPrinter::HighResolution);
QPageSetupDialog dlg(&printer);
if(QDialog::Accepted == dlg.exec())
{
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("D:/test.pdf");
QPainter painter;
if (! painter.begin(&printer))
{
// failed to open file
qWarning("failed to open file, is it writable?");
return ;
}
int count = ui->listWidget->count();
for(int i = 0, j = 1; i < count; i++)
{
QString text = ui->listWidget->item(i)->text();
if(text != "")
{
//printer.pageSize().width();
painter.drawText(10, painter.fontMetrics().height()*j++, text);
}
else if(text == "" && i < count - 1)
{
if (! printer.newPage()) //分页
{
qWarning("failed in flushing page to disk, disk full?");
break;
}
j = 1;
}
}
painter.end();
qDebug() << "print finished";
}
}
我们先定义了一个QPrinter对象,为下面的打印文本操作做准备;然后,再使用该对象定义一个QPageSetupDialog对象;最后,调用该类的exec()函数,显示出该页面设置 对话框。
在这个页面中,我们可以设置打印所用的页面的大小和文本的打印方向,以及文本的边距等。如果在设置之后点击了确定按钮,则代码中的exec()会返回Accepted,在此,我们使用输出到文件的方式来将这些文本打印到D:/test.pdf文件中。
至于实际的打印动作,还是由QPainter类来实现的,这得益于计算机的抽象机制,允许我们使用同一套API来完成向屏幕和打印机的输出。
打开test.pdf,就可以看到我们打印的内容了。
“PrintDialog”按钮的实现代码如下:
//打印对话框
void Widget::on_printdlg_clicked()
{
QPrinter printer;
//设置页数范围
printer.setFromTo(1, list.size());
QPrintDialog printDlg(&printer, this);
if(QDialog::Accepted == printDlg.exec())
{
QPainter painter;
if (! painter.begin(&printer))
{
// failed to open file
qWarning("failed to open file, is it writable?");
return ;
}
int count = ui->listWidget->count();
for(int i = 0, j = 1; i < count; i++)
{
QString text = ui->listWidget->item(i)->text();
if(text != "")
{
painter.drawText(10, painter.fontMetrics().height()*j++, text);
}
else if(text == "" && i < count - 1)
{
if (! printer.newPage())
{
qWarning("failed in flushing page to disk, disk full?");
break;
}
j = 1;
}
}
painter.end();
qDebug() << "print finished";
}
}
其实,该类的使用方式和上一个类似。都是先定一个QPrinter对象,然后使用该对象来创建一个QPrintDialog对话框,最后调用exec()来显示该对话框。如下:
并且,也正确显示了我们所设置的页面范围。
另外,在代码中,我们去掉了输出到文件的代码,此时,如果点击确定且计算机连接了可用的打印机的话,就会将内容发送到打印机进行打印。
至于打印预览也一样,只不过是将内容输入到屏幕,展示给用户看而已。实现代码如下:
//打印预览对话框
void Widget::on_printpreviewdlg_clicked()
{
QPrinter printer(QPrinter::HighResolution);
QPrintPreviewDialog printPreDlg(&printer, this);
connect(&printPreDlg, &QPrintPreviewDialog::paintRequested,
[=, this](QPrinter* printer)
{
QPainter painter;
if (! painter.begin(printer))
{
// failed to open file
qWarning("failed to open file, is it writable?");
return ;
}
int count = ui->listWidget->count();
for(int i = 0, j = 1; i < count; i++)
{
QString text = ui->listWidget->item(i)->text();
if(text != "")
{
painter.drawText(10, painter.fontMetrics().height()*j++, text);
}
else if(text == "" && i < count - 1)
{
if (! printer->newPage())
{
qWarning("failed in flushing page to disk, disk full?");
break;
}
j = 1;
}
}
painter.end();
});
printPreDlg.exec();
}
同样是先创建一个QPrinter对象,然后使用该对象来创建一个QPrintPreviewDialog对象来显示预览对话框。不同的是,预览对话框的内容是通过一个paintRequested信号来请求的,所以,我们连接了该信号,在槽函数中将要显示的文本通过QPainter 输出到预览对话框中。运行结果如下:
注意,我们在连接paintRequestd信号时,使用了C++11的lambda表达式,所以还要在pro文件中添加对c++11的支持。即添加下面这行代码:
CONFIG += c++11
---------------------
作者:求道玉
来源:CSDN
原文:https://blog.csdn.net/amnes1a/article/details/70597506
版权声明:本文为博主原创文章,转载请附上博文链接!
Qt中的打印操作的更多相关文章
- 第32课 Qt中的文件操作
1. Qt的中IO操作 (1)Qt中IO操作的处理方式 ①Qt通过统一的接口简化了文件和外部设备的操作方式 ②Qt中的文件被看作一种特殊的外部设备 ③Qt中的文件操作与外部设备的操作相同 (2)IO操 ...
- Qt 中QString 字符串操作:连接、组合、替换、去掉空白字符
Qt中的字符串类 QString类 保存了16位Unicode值,提供了丰富的操作.查询和转换等函数. QString 字符串有如下几个操作符: (1) "+" 用于组合两个字符串 ...
- 4.QT中进程操作,线程操作
QT中的线程操作 T19Process.pro SOURCES += \ main.cpp CONFIG += C++11 main.cpp #include <QCoreApplicat ...
- Qt Graphics-View的打印功能实现
本文来研究一下Qt Graphics-View的打印功能实现. 在Qt的官方文档中介绍了Graphics-View的打印相关内容. Qt中对打印的支持是有一个独立的printsupport模块来完成的 ...
- qt中的拖拽及其使用技巧
关于qt中的拖放操作,首先可以看这篇官方文档:http://doc.qt.io/qt-5.5/dnd.html 一.QDrag 首先是创建QDrag,可以在mousePressEvent或者mouse ...
- Qt中如何禁掉所有UI操作以及注意事项(处理各个widget的eventFilter这一层,但是感觉不好,为什么不使用QApplication呢)
刚做完的一个项目,在测试时出现了一个问题:由于多线程的存在,当进行语音识别时:如果用户点击程序界面上的button或者其他接受点击事件后会发出信号的widget时,程序会crash ! 后来尝试着从多 ...
- 4.关于QT中的QFile文件操作,QBuffer,Label上添加QPixmap,QByteArray和QString之间的区别,QTextStream和QDataStream的区别,QT内存映射(
新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CON ...
- Qt中与文件目录相关操作
一.与文件目录操作有关操作. Qt中与文件目录相关的操作在QDir中,需加入#include <QDir>语句. QDir::drives()是列出电脑根目录下的所有目录,返回的是QFil ...
- 4.关于QT中的QFile文件操作,QBuffer,Label上加入QPixmap,QByteArray和QString之间的差别,QTextStream和QDataStream的差别,QT内存映射(
新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CON ...
随机推荐
- 【Visual Studio】error C2220: 警告被视为错误 - 没有生成“object”文件 (转)
原文转自 http://www.cnblogs.com/kex1n/archive/2011/10/19/2217266.html [错误原因] 该文件的代码页为英文,而我们系统中的代码页为中文. [ ...
- 不需 porting 就可充電的 charger ic。
Origin : 今天同事問我一個關於配有 RT9458 charger ic 的手機的問題, 這手機可能要送到廠商那, 需要 porting charger ic, 看了一下,跟他說這個充電部份不需 ...
- HDU 4722:Good Numbers(数位DP)
类型:数位DP 题意:定义一个Good Number 为 一个数所有位数相加的和%10==0.问[A,B]之间有多少Good Number. 方法: 正常“暴力”的定义状态:(i,d,相关量) 定义d ...
- codevs——2956 排队问题
2956 排队问题 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 有N个学生去食堂,可教官规定:必须2人或3 ...
- 两种const函数
有两种const函数,声明如下:1.const T func();2.T func() const;第一种表示返回的是const的类型,也即返回的值不能作为左值,楼主懂的.第二种表示该成员函数不能修改 ...
- eclipse 添加 maven 小结
今天想创建了一个maven项目,由于之前重装系统,maven的一些配置要重新进行配置,y有时候一点小问题那真是一路曲折,为防止之后再遇到此问题,小结一下吧! 环境: eclipse apache- ...
- commons-lang3工具类学习--------ObjectUtils
Object工具类 allNotNull(Object... values) 检查所有元素是否为空,返回一个boolean 如果有一个元素为空返回false,所有元素不为空或元素为empty返回tru ...
- VS2010 + WinDDK 搭建驱动开发环境(转)
因工作需要,需要研究一下Windows驱动开发.我们知道,编译驱动程序主要是通过两种方案:第一种是通过WinDDK提供的build命令+source文件进行编译:另外一种是通过VC的IDE进行编译. ...
- Java中将List转成逗号数组的方案
说明:逗号字符串转成数组或者List都是可以的,反过来依然可行:但是如果是List<String>转List<Integer>,基本误解,在Java 7只能for循环,如果在J ...
- input 对伪元素(:before :after)的支持情况
最近做一个自定义视觉效果的Switch组件,用到了 input:radio 和 label,并在label里用伪元素 :before 模拟状态的切换效果. 但是同事评审的时候说可以不用label,直接 ...