PDA

View Full Version : GraphicsScene print



^NyAw^
10th January 2017, 12:00
Hi,

I'm trying to print a QGraphicsScene and I'm having some problems with the resulting size.



int iDPIs = 300;
qreal qResolutionMmPx = 1 / ((double)iDPIs / 25.4); //mm / px

QPrinter qPrinter;
QString qPDFFileName = "painter.pdf";
qPrinter.setOutputFormat(QPrinter::PdfFormat);
qPrinter.setOutputFileName(qPDFFileName);
qPrinter.setPageSize(QPrinter::A4);
qPrinter.setResolution(iDPIs);

QPainter qPainter(&qPrinter);

qPainter.drawRect(50/qResolutionMmPx,50/qResolutionMmPx,100/qResolutionMmPx,100/qResolutionMmPx);

This draws a 100x100mm rect perfectly.

This code tryies to print using a graphics scene:


int iDPIs = 300;
qreal qResolutionMmPx = 1 / ((double)iDPIs / 25.4); //mm / px

pqScene = new QGraphicsScene(this);
ui.graphicsView->setScene(pqScene);
pqScene->addRect(0,0,100/qResolutionMmPx,100/qResolutionMmPx,QPen(Qt::blue)); //100x100mm desired rect

QPrinter qPrinter;
QString qPDFFileName = "scene.pdf";
qPrinter.setOutputFormat(QPrinter::PdfFormat);
qPrinter.setOutputFileName(qPDFFileName);
qPrinter.setPageSize(QPrinter::A4);
qPrinter.setResolution(iDPIs);

QPainter qPainter(&qPrinter);
pqScene->render(&qPainter);

This always gives me a rect about 203mm. Also changing the size of the rect item gives me always the same result size.

What I found is that changing the scene rect also changes the resulting size, so


pqScene->setSceneRect(0,0,1000,1000);

Gives me a rect that is 76,6mm

Can anyone explain me what I'm not understanding?

Thanks,

d_stranz
10th January 2017, 16:38
Your view (ui.graphicsView) is on screen, right? I think you have a mismatch between the screen resolution (75 DPI maybe) and size of the view and your printer resolution and page size, as well as possibly not taking into account printer margins. Is your view also calling fitInView() in the resize method?

What happens if you render the view rather than the scene? (ui.graphicsView.render( &qPainter ))

^NyAw^
10th January 2017, 17:14
Your view (ui.graphicsView) is on screen, right?

Yes.



I think you have a mismatch between the screen resolution (75 DPI maybe) and size of the view and your printer resolution and page size, as well as possibly not taking into account printer margins

This is what I don't understand how it works. The screen resolution returns 96 DPI. My printer will use 203 DPI but for testing purposes I'm exporting it to PDF with 300 DPI by now.



Is your view also calling fitInView() in the resize method?

I have added it now with same result.



What happens if you render the view rather than the scene? (ui.graphicsView.render( &qPainter ))

This gives me a size of 36,84mm.


What I have addeed now and seems to work is:


//Adding items
int iScreenDPIs = logicalDpiX(); //96 DPI
qreal qScreenResolutionMmPx = 1 / ((double)iScreenDPIs / 25.4);
pqScene->setSceneRect(0,0,210/qScreenResolutionMmPx,297/qScreenResolutionMmPx);
pqScene->addRect(50/qScreenResolutionMmPx,50/qScreenResolutionMmPx,100/qScreenResolutionMmPx,100/qScreenResolutionMmPx,QPen(Qt::blue));

//Add text item to see if it mantain the font "point size"
QFont qFont("Arial",10);
QGraphicsItemText *pqTextItem = pqScene->addText("TEST"·,qFont);
pqTextItem->setPos(50/qResolutionMmPx,50/qResolutionMmPx);

//Rendering
int iPrinterDPIs = 300; //Desired printing resolution
qreal qPrinterResolutionMmPx = 1 / ((double)iPrinterDPIs / 25.4);
pqScene->render(&qPainter,QRectF(0,0,210/qPrinterResolutionMmPx ,297/qPrinterResolutionMmPx )); //Render the scene scaled to the desired size

As it seems to adapt the scene to the deisred rect.

I really do not fully uderstand why it renders right.

I need to print some images and texts that the user can position, change font family and size, ... And the firts problem that I found was when adding the text item as it takes the screen DPIs to create.

^NyAw^
11th January 2017, 10:25
Well,

First of all,


int iScreenDPIs = logicalDpiX(); //96 DPI
qreal qScreenResolutionMmPx = 1 / ((double)iScreenDPIs / 25.4);
pqScene->setSceneRect(0,0,210/qScreenResolutionMmPx,297/qScreenResolutionMmPx);


We need to set the scene rect with a mm scale because when adding a QGraphicsTextItem to the secene


QFont qFont("Arial",10);
QGraphicsItemText *pqTextItem = pqScene->addText("TEST"·,qFont);

it takes the screen DPI to calculate the size of the item. This is ok, calculating the boundingRect of the item and using this DPI gets me the real size of a printed text in Arial 10pt.

So, finally, when printing, the "render" method "maps from the source rectangle, in scene units, to a target rectangle, in device units", extracted from http://stackoverflow.com/questions/37708423/i-need-to-print-a-qgraphicsscene-to-actual-inch-mm-scale

and is for that reason that I have to calculate the destination rectangle taking the printer resolution.

Think on a CAD software for example. You can draw a rect that represents a 10x10m and you can print it as 20x20mm using the printer resolution and a scale factor.