Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt QPainter in millimetres instead of inches

I have a QPrinter that prints A4 either directly to a physical printer or a PDF. Now I'd like to use QPainter to draw in millimetres, but the current coordinate system seems to be the width and height of an A4 in inches times the resolution of the printer.

8.26 inch x 1200 res = 9912
11.69 inch x 1200 res = 14028

I have tried the following but text just ended up huge.

auto page = printer.pageRect(QPrinter::Unit::Millimeter);
painter.setWindow(QRect(0, 0, page.width(), page.height()));

How do I change this so my QPainter can draw to 210 x 297 mm instead of the above system?

This is on Windows 10 and with Qt 5.10.

like image 210
Eejin Avatar asked Dec 10 '17 00:12

Eejin


1 Answers

I tested this method on X11 (ubuntu linux) PDF print, using ScreenResolution printer mode:

painter.begin(printer);

int log_w  = 210;
int log_h  = 297;
painter.setWindow(0, 0, log_w, log_h);

int phys_w  = printer->width();
int phys_h = printer->height();
painter.setViewport(0, 0, phys_w, phys_h);

Basically, set your logical size in mm using the painter window, and give the painter's viewport the printer's physical size. This line should print a rectangle around the page with a border of 10 mm:

painter.drawRect(10, 10, log_w - 20, log_h -20);

Text should work accordingly. This code should print the word Ok at the top left corner of the rectangle:

  QFont font = painter.font();
  font.setPointSize(10); //1 cm height
  painter.setFont(font);
  painter.drawText(10, 20, "Ok");

  painter.end();

Using HighResolution printer mode, font size must be set using

font.setPixelSize(10); //1 cm height

and a QPen must be set to the painter:

QPen pen(Qt::black);
pen.setWidthF(0.2);
painter.setPen(pen);
painter.drawRect(10, 10, log_w - 20, log_h - 20);

About loss of device dependency using setPixelSize, I'm aware that here is stated:

It is possible to set the height of characters shown on the screen to a specified number of pixels with setPixelSize(); however using setPointSize() has a similar effect and provides device independence.

but I think it refers to screen only, given that here is stated:

When rendering text on a QPrinter device, it is important to realize that the size of text, when specified in points, is independent of the resolution specified for the device itself. Therefore, it may be useful to specify the font size in pixels when combining text with graphics to ensure that their relative sizes are what you expect.

like image 106
p-a-o-l-o Avatar answered Sep 26 '22 13:09

p-a-o-l-o