在Qt中,打印与在QWidget,QPixmap或者QImage绘图很相似,一般步骤如下:
1、创建绘图设备的QPrinter;
2、弹出打印对话框,QPrintDialog,允许用户选择打印机,设置属性等;
3、创建一个QPrinter的QPainter;
4、用QPainter绘制一页;
5、调用QPrinter::newPage(),然后绘制下一页;
6、重复步骤4,5,直到打印完所有页。
在Windows和Mac OS X平台,QPrinter使用系统的打印驱动程序。在Unix上,QPrinter生成脚本并把脚本发送给lp或者lpr(或者发送给程序,打印程序有函数QPrinter::setPrintProgram())。调用QPrinter::setOutputFormat (QPrinter::PdfFormat)QPrinter也可以生成PDF文件。
Figure 8.12. Printing aQImage
首先看一个简单的例子,打印一个QImage到一页纸上。
void PrintWindow::printImage(const QImage &image)
{
QPrintDialog printDialog(&printer, this);
if (printDialog.exec()) {
QPainter painter(&printer);
QRect rect = painter.viewport();
QSize size = image.size();
size.scale(rect.size(), Qt::KeepAspectRatio);
painter.setViewport(rect.x(), rect.y(),
size.width(), size.height());
painter.setWindow(image.rect());
painter.drawImage(0, 0, image);
}
}
这里,我们假设了在PrintWindow类有一个QPrinter类型的成员变量printer。当然在printImage()函数的堆上我们也可以创建一个QPrinter,但是这样不能记录用户进行打印时的设置
创建QPrintDialog,调用exec()显示出来,如果用户点击了OK返回true,否则返回false。调用exec()后,QPrinter对象就可以使用了。(也可以不显示QPrintDialog,直接调用QPrinter的成员函数进行复制也可以)
然后,我们创建QPainter,绘图设备为QPrinter。设置窗口为所显示图形的矩形,视口也同样比例,然后在(0,0)绘制图像。
通常,QPainter的窗口自动进行了初始化,打印机和屏幕有着一致的分辨率(一英寸有72到100个点),使控件的打印代码能够重用。在上面的函数中,我们自己设置来QPainter的窗口。
在一页中进行打印很简单,但是,很多应用程序需要打印多页。这时我们一次打印一页,然后调用newPage()打印另一页。这里需要解决定一个问题是要确定一页打印多少内容。在Qt中有两种方法处理多页的打印文档:
1、我们可以把数据转换为HTML格式,使用QTextDocument描述他们,QTextDocument是Qt的多文本引擎。
2、手动进行分页
下面我们来分别看一下这两种方法。第一个例子,我们想打印一个花卉的指导:一列为花的名字,另一列为文本描述。每一条的文本格式存储为:“名称:描述”。例如:Miltonopsis santanae: A most dangerous orchid species.
由于每一种花卉的数据都可以用一个字符串表示,我们可以用QStringList表示所有花卉的数据。下面的代码为使用Qt的多文本引擎进行打印的例子:
void PrintWindow::printFlowerGuide(const QStringList &entries)
{
QString html;
foreach (QString entry, entries) {
QStringList fields = entry.split(": ");
QString title = Qt::escape(fields[0]);
QString body = Qt::escape(fields[1]);
html += "<table width=/"100%/" border=1 cellspacing=0>/n"
"<tr><td bgcolor=/"lightgray/"><font size=/"+1/">"
"<b><i>" + title + "</i></b></font>/n<tr><td>" + body
+ "/n</table>/n<br>/n";
}
printHtml(html);
}
首先把QStringList转换为HTML。每一种花卉为HTML表格中的一行,调用Qt::escapte()将特殊字符’&’,’>’,’<’等用相应的HTML字符表示(’amp’,’>’,’<’),然后调用printHtml()打印文本:
void PrintWindow::printHtml(const QString &html)
{
QPrintDialog printDialog(&printer, this);
if (printDialog.exec()) {
QPainter painter(&printer);
QTextDocument textDocument;
textDocument.setHtml(html);
textDocument.print(&printer);
}
}
函数printHtml()弹出QPrintDialog对话框,负责打印一个HTML文档。这些代码可以在所有Qt的应用程序中打印任意HTML文档。
Figure 8.13. Printing a flower guide usingQTextdocument
目前,把文本转换为HTML文档用QTextDocument打印是最方便的一个方法。如果需要更多的设置,就需要我们自己进行页面布局和绘制。下面的方法就是用人工干预的方式打印花卉指南。首先看一下printFlowerGuide()函数:
void PrintWindow::printFlowerGuide(const QStringList &entries)
{
QPrintDialog printDialog(&printer, this);
if (printDialog.exec()) {
QPainter painter(&printer);
QList<QStringList> pages;
paginate(&painter, &pages, entries);
printPages(&painter, pages);
}
}
在创建QPainter,设置好打印机以后,调用函数paginate()确定那些项目在那一页。执行这个函数的结果是得到一个QStringList的列表,每一个QStringList在一页里显示,把这个结果传递给printPages()进行打印。
例如:需要打印的花卉指南有6个条目:A,B,C,D,E,F。其中A和B在第一页,C,D,E打印在第二页,F在第三页打印。
void PrintWindow::paginate(QPainter *painter, QList<QStringList> *pages,
const QStringList &entries)
{
QStringList currentPage;
int pageHeight = painter->window().height() - 2 * LargeGap;
int y = 0;
foreach (QString entry, entries) {
int height = entryHeight(painter, entry);
if (y + height > pageHeight && !currentPage.empty()) {
pages->append(currentPage);
currentPage.clear();
y = 0;
}
currentPage.append(entry);
y += height + MediumGap;
}
if (!currentPage.empty())
pages->append(currentPage);
}
函数paginate()把花会指南条目分页。根据entryHeight()计算每一个条目的高度。同时考虑页面顶端和底端的垂直距离LargeGap。
遍历所有的条目,如果这个条目可以放在当前页,就把这个条目放到当前页的列表里面。当前页排满后,把当前页放到页的列表中,开始新的一页。
int PrintWindow::entryHeight(QPainter *painter, const QString &entry)
{
QStringList fields = entry.split(": ");
QString title = fields[0];
QString body = fields[1];
int textWidth = painter->window().width() - 2 * SmallGap;
int maxHeight = painter->window().height();
painter->setFont(titleFont);
QRect titleRect = painter->boundingRect(0, 0, textWidth, maxHeight,
Qt::TextWordWrap, title);
painter->setFont(bodyFont);
QRect bodyRect = painter->boundingRect(0, 0, textWidth, maxHeight,
Qt::TextWordWrap, body);
return titleRect.height() + bodyRect.height() + 4 * SmallGap;
}
函数entryHeight()根据QPainter::boundingRect()计算每一个条目的垂直距离,图8.4表明了条目的布局和SmallGap还MediumGap的含义:
The enTRyHeight() function uses QPainter::boundingRect() to compute the vertical space needed by one entry.Figure 8.14shows the layout of a flower entry and the meaning of the SmallGap and MediumGap constants.
Figure 8.14. A flower entry's layout
void PrintWindow::printPages(QPainter *painter,
const QList<QStringList> &pages)
{
int firstPage = printer.fromPage() - 1;
if (firstPage >= pages.size())
return;
if (firstPage == -1)
firstPage = 0;
int lastPage = printer.toPage() - 1;
if (lastPage == -1 || lastPage >= pages.size())
lastPage = pages.size() - 1;
int numPages = lastPage - firstPage + 1;
for (int i = 0; i < printer.numCopies(); ++i) {
for (int j = 0; j < numPages; ++j) {
if (i != 0 || j != 0)
printer.newPage();
int index;
if (printer.pageOrder() == QPrinter::FirstPageFirst) {
index = firstPage + j;
} else {
index = lastPage - j;
}
printPage(painter, pages[index], index + 1);
}
}
}
函数printPages()的作用是调用printPage()按照顺序和打印份数打印每一页。通过QPrintDialog,用户可能需要打印多份,设置了打印范围,或者要求逆序打印。我们需要在程序中考虑这些需求
首先确定打印范围。QPrinter::fromPage()和toPage()返回用户选择的页面范围。如果没有选择,返回为0。我们进行了减1操作是因为我们的页面索引是从0开始的。如果用户没有选定范围,则打印全部,firstPage和lastPage包含量所有的页面。
然后我们打印每一页。最外层循环为用户设定的打印的份数。对于那些支持多份打印的打印机,QPrinter::numCopies()总是返回1。如果打印机驱动程序不支持多份打印,numCopies()返回到是用户指定的打印份数,有应用程序实现多份打印。(在这一节的QImage例子中,为了简单起见,我们没有考虑多份打印。)
Figure 8.15. Printing a flower guide usingQPainter
内层循环遍历打印的页数。如果页数不是第一页,调用newPage()清楚原来的页面开始填充新页面。调用printPage()打印每一页。
void PrintWindow::printPage(QPainter *painter,
const QStringList &entries, int pageNumber)
{
painter->save();
painter->translate(0, LargeGap);
foreach (QString entry, entries) {
QStringList fields = entry.split(": ");
QString title = fields[0];
QString body = fields[1];
printBox(painter, title, titleFont, Qt::lightGray);
printBox(painter, body, bodyFont, Qt::white);
painter->translate(0, MediumGap);
}
painter->restore();
painter->setFont(footerFont);
painter->drawText(painter->window(),
Qt::AlignHCenter | Qt::AlignBottom,
QString::number(pageNumber));
}
函数printPage()打印页面中的每一个条目。首先用printBox()打印标题,然后用printBox()打印描述。在每一页的底端打印页码。
Figure 8.16. The flower guide's page layout
void PrintWindow::printBox(QPainter *painter, const QString &str,
const QFont &font, const QBrush &brush)
{
painter->setFont(font);
int boxWidth = painter->window().width();
int textWidth = boxWidth - 2 * SmallGap;
int maxHeight = painter->window().height();
QRect textRect = painter->boundingRect(SmallGap, SmallGap,
textWidth, maxHeight,
Qt::TextWordWrap, str);
int boxHeight = textRect.height() + 2 * SmallGap;
painter->setPen(QPen(Qt::black, 2, Qt::SolidLine));
painter->setBrush(brush);
painter->drawRect(0, 0, boxWidth, boxHeight);
painter->drawText(textRect, Qt::TextWordWrap, str);
painter->translate(0, boxHeight);
}
printBox()首先绘制一个矩形框,然后在矩形框中绘制文本。
知识拓展:
分享到:
相关推荐
在本文中,我们将深入探讨如何使用Qt框架进行图片打印,主要参考标题为“Qt 打印图片 打印机 例程”的项目。Qt是一个功能强大的C++库,提供了丰富的图形用户界面(GUI)功能,其中包括对打印机的支持。在Windows环境...
在本文中,我们将深入探讨如何使用Qt库进行打印和预览功能。Qt是一个跨平台的应用程序开发框架,广泛用于创建桌面、移动以及嵌入式系统的用户界面。在标题"Qt例子—打印和预览"中提到的示例,提供了一个在窗口中输入...
在Qt框架中,打印功能是通过一系列的类和方法实现的,主要涉及到`QPrinter`、`QPrintPreviewDialog`、`QPainter`等组件。这些工具使得开发者能够轻松地将应用程序中的数据发送到打印机或者预览打印效果。现在我们...
Qt 控制打印机调整真实页面大小及问题解决方法 在 Qt 中控制打印机调整真实页面大小是一个常见的问题,本文将详细讲解如何使用 Qt 来控制打印机的页面大小,并解决一些常见的问题。 首先,我们需要了解 Qt 中的...
在Qt框架中,打印预览是一项重要的功能,它允许用户在实际打印之前查看文档或网页的打印效果。本文将深入探讨如何使用Qt实现一个简单的打印预览系统,主要基于描述中的"qt 的简单的打印预览"例子。 首先,我们要...
在VB6(Visual Basic 6)中,`Printer`对象是用于控制打印机的基本接口,它允许程序员直接向打印机发送指令,实现文字、图形和表格的打印功能。本篇将深入探讨如何利用`Printer`对象来打印文字和表格,以及相关的...
1. 包含了zint原始代码,可...2. 采用zint输出svg格式的一维条形码,然后把svg图片转换为png,然后在qt中的label显示,并且把png文件存到本地。 3. 采用QPrinter的方式,直接打印png图片,在条形码机器上输出没有问题。
函数,仅显示单个区域,进行grabWidget并drawPixmap到painter上,再调用printer->newPage();新建一页,再仅显示下一个小块,在新的一页上打印下一个小块!借鉴了...
在Delphi编程环境中,Printer组件是用于实现打印功能的核心组件,它可以让你的程序与打印机进行交互,无需通过对话框或用户界面来设置打印参数。"Delphi printer打印用法示例.rar"是一个压缩包,其中包含的代码示例...
Ext.Printer 打印,ext打印 Ext.Printer 打印,ext打印 Ext.Printer 打印,ext打印 Ext.Printer 打印,ext打印 Ext.Printer 打印,ext打印 Ext.Printer 打印,ext打印
本篇将详细讲解如何在Qt 5中实现截屏打印功能,以及如何利用Qt支持的PDF导出。 Qt 5的截图功能主要依赖于`QScreen`类,它提供了获取系统屏幕信息的能力,而`QPixmap`类则用于处理图像数据。要实现截屏,首先我们...
QT_Printer-master 是一个基于Qt库的打印功能示例项目,它主要展示了如何在Qt环境中实现打印功能。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备。这个压缩包包含了源代码、编译配置和其他...
"Qt:textEdit转PDF和打印"这个主题涉及到的是如何在Qt环境中利用textEdit组件将文本内容转换成PDF格式,并进行打印预览及实际打印操作,特别是在mac操作系统上。 首先,Qt的textEdit是一个富文本编辑器,它允许用户...
printer.setPageMargins(QMarginsF(10, 10, 10, 10), QPrinter::Millimeter); QTextDocument document; document.setHtml(wesiOperateWidget::MakeDataToHtml()); document.print(&printer); ``` 对于实际的...
目前针对QT打印PDF和获取打印机状态,通过几天的确认发现三个层面的获取状态 1. QT应用程序级别的获取打印机状态,通过QPrint 2. 通过LINUX系统级别的获取 lpstat -l -p 3. 通过打印机厂家的API获得计算机状态 目前...
在描述中提到的“qt版本画图软件支持保存打印功能”,这意味着该软件利用了Qt库中的图形和打印相关模块来实现这些功能。下面将详细讲解Qt在画图和保存打印方面的实现。 1. **Qt绘图基础** Qt提供了一个名为`...
**Qt打印技术详解** 在软件开发中,有时候我们需要将数据或者界面内容输出到打印机,Qt框架为此提供了一套完善的打印支持。"Qt打印示例.rar"这个压缩包中包含了一个关于Qt打印功能的实例,我们可以从中学到如何在Qt...
"一个免费的Web Printer打印控件" 提供了解决这一问题的一种解决方案,它允许用户通过Web界面实现打印操作,极大地拓展了打印功能的使用场景。 这个控件具有跨平台的特性,支持多种编程语言,如ASP(Active Server ...
本文将深入探讨“Printer first Gird打印预览控件”及其VB源程序,这是一种专用于实现打印预览功能的组件,对于开发者来说,能够极大地提升应用程序的专业性和用户体验。 首先,"Printer first Gird"这个名字暗示了...
Android蓝牙打印,文档类型word,打印机HP-officejet100 L411 ,采用打印app为第三方应用PrinterShare (需要购买注册key) 根据POI生成word模板,保存至本地,通过调用PrinterShare实现打印,兼容各类打印机,唯一缺点...