简体   繁体   English

使用 QPrinter 打印 y 页的 x 页

[英]page x of y using QPrinter

im generating a pdf file from html code using qt:我使用qt从html代码生成pdf文件:

QTextDocument *document = new QTextDocument();
document->setHtml(htmlContent);

QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("filename.pdf");

document->print(printer);

Is it possible to have the page information "Page X of Y" instead of only the page number?是否可以使用页面信息“Y 的 X 页”而不仅仅是页码? If yes, how?如果是,如何?

The solution I propose is based on this code .我提出的解决方案基于此代码 I have added the necessary support for HighResolution我已经添加了对高分辨率的必要支持

static const int textMargins = 12; // in millimeters
static const int borderMargins = 10; // in millimeters

static double mmToPixels(QPrinter& printer, int mm)
{
    return mm * 0.039370147 * printer.resolution();
}

static void paintPage(int pageNumber, int pageCount,
                      QPainter* painter, QTextDocument* doc,
                      const QRectF& textRect, qreal footerHeight)
{


    painter->save();
    // textPageRect is the rectangle in the coordinate system of the QTextDocument, in pixels,
    // and starting at (0,0) for the first page. Second page is at y=doc->pageSize().height().
    const QRectF textPageRect(0, pageNumber * doc->pageSize().height(), doc->pageSize().width(), doc->pageSize().height());
    // Clip the drawing so that the text of the other pages doesn't appear in the margins
    painter->setClipRect(textRect);
    // Translate so that 0,0 is now the page corner
    painter->translate(0, -textPageRect.top());
    // Translate so that 0,0 is the text rect corner
    painter->translate(textRect.left(), textRect.top());
    doc->drawContents(painter);
    painter->restore();
    QRectF footerRect = textRect;
    footerRect.setTop(textRect.bottom());
    footerRect.setHeight(footerHeight);
    painter->drawText(footerRect, Qt::AlignVCenter | Qt::AlignRight, QObject::tr("Page %1 of %2").arg(pageNumber+1).arg(pageCount));
}

static void printDocument(QPrinter& printer, QTextDocument* doc)
{
    QPainter painter( &printer );
    doc->documentLayout()->setPaintDevice(&printer);
    doc->setPageSize(printer.pageRect().size());
    QSizeF pageSize = printer.pageRect().size(); // page size in pixels
    // Calculate the rectangle where to lay out the text
    const double tm = mmToPixels(printer, textMargins);
    const qreal footerHeight = painter.fontMetrics().height();
    const QRectF textRect(tm, tm, pageSize.width() - 2 * tm, pageSize.height() - 2 * tm - footerHeight);
    doc->setPageSize(textRect.size());

    const int pageCount = doc->pageCount();

    bool firstPage = true;
    for (int pageIndex = 0; pageIndex < pageCount; ++pageIndex) {

        if (!firstPage)
            printer.newPage();

        paintPage(pageIndex, pageCount, &painter, doc, textRect, footerHeight );
        firstPage = false;
    }
}

Example:示例:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QTextDocument *document = new QTextDocument();
    QTextCursor cursor(document);
    QTextBlockFormat blockFormat;


    for(int i=0; i < 10; i++){
        cursor.insertBlock(blockFormat);
        cursor.insertHtml(QString("<h1>This is the %1 page</h1>").arg(i+1));
        blockFormat.setPageBreakPolicy(QTextFormat::PageBreak_AlwaysBefore);
    }


    QPrinter printer(QPrinter::HighResolution);
    printer.setPageSize(QPrinter::A4);
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName("filename.pdf");;

    printDocument(printer, document);
    return app.exec();
}

The above Is a good solution but will break your QTextDocument object if you work with it after the print.以上是一个很好的解决方案,但如果您在打印后使用它会破坏您的 QTextDocument 对象。 I have a QTextDocument that is a member of a dialog and when the calling function that provided the Printer (paintDevice) loses scope it crashes the document.我有一个 QTextDocument,它是一个对话框的成员,当提供打印机 (paintDevice) 的调用函数失去范围时,它会使文档崩溃。

I suggest getting a poiner of the current paintDevice at the start of the function then restoring it at the end.我建议在函数开始时获取当前paintDevice的指针,然后在最后恢复它。

    static void printDocument(QPrinter& printer, QTextDocument* doc)
{

    QPaintDevice * oldDevice=doc->documentLayout()->paintDevice();
    doc->documentLayout()->setPaintDevice(&printer);    

    doc->documentLayout()->setPaintDevice(oldDevice);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM