我正在尝试以A4为单位打印发票凭证,而不是默认的设备单位.除了将单位更改为毫米时,打印文档上的文本的分数不再与例如Word或Adobe Illustrator中的分数相匹配.我尝试将点大小转换为相应的像素大小,但它们存在问题.
QFont :: SetPixelSize只接受一个int,所以如果计算值低于1,它将转换为0
font.setPixelSize((9.0 * 72.0) / printer.resolution());
Run Code Online (Sandbox Code Playgroud)
而另一种方法使文本的垂直尺寸正确,但有一些文物:
int phys_w = printer.width();
font.setPointSizeF((9.0 / phys_w) * 210.0);
Run Code Online (Sandbox Code Playgroud)

你可以在哪里看到一些角色之间异常大的差距.(也许在Qt中有一些精确的问题,它的文本绘图代码?)
这是一个显示问题的最小例子:
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setFullPage(true);
printer.setPageMargins(QMarginsF(0, 0, 0, 0));
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("invoice.pdf");
QPainter painter(&printer);
auto page_size = printer.pageRect(QPrinter::Unit::Millimeter);
painter.setWindow(page_size.toRect());
QFont font = painter.font();
// Either this
font.setPixelSize((9.0 * 72.0) / printer.resolution());
// or this
int phys_w = printer.width();
font.setPointSizeF((9.0 / phys_w) * 210.0);
painter.setFont(font);
painter.drawText(35, 46, "John Doe");
Run Code Online (Sandbox Code Playgroud)
如何以毫米(或任意单位)定位并使文本大小正确(或正确重新计算)?
这是在Qt 5.10.0和Windows 10上.
编辑 最后我选择了10倍的比例增加(十分之一毫米),这修复了setPointSizeF可见的字距调整问题.现在我对缩放的最后一个问题是设置一条线的宽度和其他形状(QPen :: setWidth),我找不到计算所以它以毫米为单位.
编辑 最后,线宽不需要任何重新计算.最终代码如下:
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setFullPage(true);
printer.setPageMargins(QMarginsF(0, 0, 0, 0));
printer.setOutputFormat(QPrinter::NativeFormat);
QPainter painter(&printer);
painter.setWindow(0, 0, 2100, 2970);
painter.setViewport(0, 0, printer.width(), printer.height());
QFont font(fontFamily, 0, weight, italic);
font.setPointSizeF(static_cast<float>(pixelSize) / printer.width() * 2100);
Run Code Online (Sandbox Code Playgroud)
我认为你在应该乘法的地方除法,反之亦然。看看明确写出的单位:
9 点 *(1 英寸/72 点)*(printer.res 像素/英寸)
将单位相乘,分子得到 (点 * 英寸 * 像素) ,分母得到 (点 * 英寸) 。取消类似的单位,分子中就得到像素。所以计算应该是:
font.setPixelSize(9.0 / 72.0 * printer.resolution());
Run Code Online (Sandbox Code Playgroud)
对于你的第二个问题,
QPen::setWidthF(w*printer.resolution()/25.4);
Run Code Online (Sandbox Code Playgroud)
其中 w 是您所需的宽度(以毫米为单位)。