Qt 使用QPrinter设置自定义纸张尺寸不需要';无法正确打印

Qt 使用QPrinter设置自定义纸张尺寸不需要';无法正确打印,qt,printing,qprinter,Qt,Printing,Qprinter,我需要能够从qt(Qgraphicscene或QImage的渲染内容)按比例打印,可以在普通打印机、pdf上打印,也可以在自定义打印机(包括卷式进纸)上打印 似乎任何适用于标准打印机的操作都会在自定义打印机上失败,反之亦然 我现在已经在定制打印机上完成了预期的打印工作(在不同的打印机上来回切换) 我根据长宽比设置了所需的自定义尺寸和首选方向 我打开一个打印对话框(甚至检查供应-纸张已设置为所需尺寸,方向已按预期设置) 打印: 在定制打印机上,我得到正确的尺寸,如果供应量较小,则根据需要打印剪辑

我需要能够从qt(Qgraphicscene或QImage的渲染内容)按比例打印,可以在普通打印机、pdf上打印,也可以在自定义打印机(包括卷式进纸)上打印

似乎任何适用于标准打印机的操作都会在自定义打印机上失败,反之亦然

我现在已经在定制打印机上完成了预期的打印工作(在不同的打印机上来回切换)

  • 我根据长宽比设置了所需的自定义尺寸和首选方向

  • 我打开一个打印对话框(甚至检查供应-纸张已设置为所需尺寸,方向已按预期设置)

  • 打印:
    在定制打印机上,我得到正确的尺寸,如果供应量较小,则根据需要打印剪辑。页边距设置也正确。
    在Pdf上,我得到了一份按要求定制大小的文件,打印正确-但方向不受尊重!!!(即使打印对话框正确显示)-参见图 在HP打印机上,我得到一个白色页面-没有打印任何内容

#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[])
{
QApplication应用程序(argc、argv);
//一些场景打印-显示矩形,便于测量
qgraphicscene*s=新的qgraphicscene();
s->SETSCEN竖立(-500,-500,1500,1500);
s->setBackgroundBrush(Qt::红色);
QGraphicsView*视图=新的QGraphicsView();
查看->设置场景;
查看->显示();
qreal-in=72;
QRectF canvasRect(-0.1*in,-0.1*in,6*in,4*in);
Q实际边距=0.1*in;
QRectF actualCanvasRect=调整后的画布(边距、边距、-边距、-边距);
//这是真实的场景
QGraphicsRectItem*contourItem=新的QGraphicsRectItem(actualCanvasRect);
轮廓项目->退刀(Qt::蓝色);
s->addItem(项目);
//部分位于画布上的项目(以便我可以检查边距)
QGraphicsRectItem*项目=新的QGraphicsRectItem(-0.5*in,-in,2*in,3*in);
项目->退刀(Qt::黄色);
s->addItem(项目);
//实际印刷:
//在给定打印机上使用用户边距按比例打印场景
打印机;
QPrinter::Orientation=(actualCanvasRect.width()>
实际NVASRECT.height()?
QPrinter::横向:QPrinter::纵向);
打印机。设置方向(定向);
printer.setPaperSize(canvasRect.size(),QPrinter::Point);
打印机.setPageMargins(页边距、页边距、页边距、页边距、QPrinter::Point);
QPrintDialog打印对话框(&打印机);
if(printDialog.exec()!=QDialog::Accepted)
{
qDebug(“对话框取消”);
返回1;
}
油漆工;
如果(!painter.begin(&打印机))
{
qDebug(“无法打开打印机”);
返回1;
}
//渲染内容,剪裁到打印机页面大小,并从一点缩放到设备像素
QRectF source=实际值CANVASRECT;
//将目标rect转换为DevicePixel并将剪辑转换为页面
QRectF page=printer.pageRect(QPrinter::DevicePixel);
qreal scale=printer.resolution()/in;
QRectF target=QRectF(page.topLeft(),source.size()*比例);
target&=page;//将目标rect剪辑到page
//将source rect剪切到页面-如果没有此选项,如果打印机纸张较小,则会出现不必要的缩放
source&=printer.pageRect(QPrinter::Point);
s->渲染(&绘制、目标、源);
结束();
返回app.exec();
}
我不明白为什么pdf会创建一个肖像页面,即使我明确要求横向(不改变打印对话框:参见图片)。(宽度和高度颠倒,但正确-文档属性显示4x6,页面尝试正确打印和缩放)

更重要的是,我不明白为什么一台典型的激光喷射打印机不打印任何东西——空白页——或者有时只打印一张简单的画布,它可以根据需要进行缩放。
但是,如果我从HP更改“打印”对话框中的任何属性,以及任何不相关的属性(如纸张来源或纸张类型……),它都会正确打印

我做错了什么


(使用Qt4.7和5.5,必须在4.7-Windows上工作,尚未尝试Linux)

猜测这里,您可以尝试将
painter.begin()
移动到
s->render(…)
之前?如果绘制引擎在
begin()
处存储一些数据,而这些数据只有在更改打印对话框中的属性时才会更新?
painter.begin()
是在对话框完成后进行的-它和渲染之间的唯一一件事是计算渲染的源和目标。并且渲染执行正确-打印机页面设置不正确。移动它并没有什么区别。似乎这就是它应该如何行动。此处来自文档:void QPrinter::setPaperSize(const QSizeF&paperSize,Unit Unit)根据单位中的纸张大小设置纸张大小。请注意,无论当前打印机方向设置为什么,纸张大小都是在纵向布局中定义的。
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QPrinter>
#include <QPrintDialog>

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

    // some scene to print - show rectangle for easy measure
    QGraphicsScene* s = new QGraphicsScene();
    s->setSceneRect(-500, -500, 1500, 1500);
    s->setBackgroundBrush(Qt::red);
    QGraphicsView* view = new QGraphicsView();
    view->setScene(s);
    view->show();
    qreal in = 72;
    QRectF canvasRect(-0.1*in, -0.1*in, 6*in, 4*in);
    qreal margins = 0.1*in;
    QRectF actualCanvasRect = canvasRect.adjusted(margins,margins,-margins,-margins);
    // this is to show actual scene
    QGraphicsRectItem* contourItem = new QGraphicsRectItem(actualCanvasRect);
    contourItem->setBrush(Qt::blue);
    s->addItem(contourItem);
    // an item partially on canvas (so I can check margins)
    QGraphicsRectItem* item = new QGraphicsRectItem(-.5*in, -in, 2*in, 3*in);
    item->setBrush(Qt::yellow);
    s->addItem(item);

    // actual printing:

    // print the scene, to scale, using user margins, on given printer
    QPrinter printer;
    QPrinter::Orientation orient = (actualCanvasRect.width() >
                                    actualCanvasRect.height() ?
                                    QPrinter::Landscape : QPrinter::Portrait);
    printer.setOrientation(orient);
    printer.setPaperSize(canvasRect.size(), QPrinter::Point);
    printer.setPageMargins(margins, margins, margins, margins, QPrinter::Point);

    QPrintDialog printDialog(&printer);
    if (printDialog.exec() != QDialog::Accepted)
    {
        qDebug("dialog canceled");
        return 1;
    }

    QPainter painter;
    if (! painter.begin(&printer))
    {
        qDebug("failed to open printer");
        return 1;
    }

    // render the contents, clipped to printer page size, and scaled from point to device pixel

    QRectF source = actualCanvasRect;

    // convert target rect to DevicePixel and clip to page
    QRectF page = printer.pageRect(QPrinter::DevicePixel);
    qreal scale = printer.resolution()/in;
    QRectF target = QRectF(page.topLeft(), source.size() * scale);
    target &= page; // clip target rect to page

    // clip source rect to page - without this, if printer paper is smaller I get unwanted scaling
    source &= printer.pageRect(QPrinter::Point);

    s->render(&painter, target, source);
    painter.end();

    return app.exec();
}