Printing with a coordinate system given in millimeters
I was wondering what the best (simple and efficient) way would to for printing in Qt when the given coordinate system is defined in absolute coordinates given in millimeters.
To better explain the problem: I have a definition of what needs to printed specified by different "tokens" (point, line, rectangle, text, etc.) with coordinates (and text sizes) given in millimeters. The positions are relative to the top left corner of a standard A4 page.
Re: Printing with a coordinate system given in millimeters
Use QPainter::setWindow() and QPainter::setViewport() to inform Qt about logical and physical coordinates respectively. You can also use GraphicsView with a scene that has dimensions reflecting the logical coordinates that you want to have.
Re: Printing with a coordinate system given in millimeters
Thank you for the hint. It works just fine except when settings the font size where I'm stuck.
I the following code example the coordinate translation works fine except for the font size that needs to either set in pixel or point.
Code:
{
Q_OBJECT
public:
Report(const QString& theTitle, int theNumberOfPages) : itsTitle(theTitle), itsNumberOfPages(theNumberOfPages) {}
void preview();
void printPage
(QPainter* thePainter,
int thePage
);
private slots:
void printDocument
(QPrinter* thePrinter
);
private:
int itsNumberOfPages;
};
void Report::preview()
{
QPrintPreviewDialog aPreview(&aPrinter, 0);
connect(&aPreview,
SIGNAL(paintRequested
(QPrinter *)),
this,
SLOT(printDocument
(QPrinter *)));
aPreview.exec();
}
void Report
::printDocument(QPrinter* thePrinter
) {
thePrinter->setFromTo(1, itsNumberOfPages);
aProgress.setWindowModality(Qt::ApplicationModal);
aProgress.setWindowTitle(itsTitle);
aProgress.setMinimum(thePrinter->fromPage() - 1);
aProgress.setMaximum(thePrinter->toPage());
// Configure a painter with local coordinate system in 1/10th of a millimeter based on an A4 landscape page
aPainter.begin(thePrinter);
int aLogicalWidth = 21000;
int aLogicalHeight = 29700;
aPainter.setWindow(0, 0, aLogicalWidth, aLogicalHeight);
int aPhysicalWidth = thePrinter->width();
int aPhysicalHeight = thePrinter->height();
aPainter.setViewport(0, 0, aPhysicalWidth, aPhysicalHeight);
// Print all pages
bool aFirstPage = true;
for (int aPage = thePrinter->fromPage(); aPage <= thePrinter->toPage(); ++aPage)
{
if (!aFirstPage)
thePrinter->newPage();
qApp->processEvents();
if (aProgress.wasCanceled())
break;
// Print page
printPage(&aPainter, aPage);
aProgress.setValue(aPage);
aFirstPage = false;
}
aPainter.end();
}
void Report
::printPage(QPainter* thePainter,
int thePage
) {
// Set pen
aPen.setColor(Qt::black);
aPen.setWidth(0);
aPen.setStyle(Qt::SolidLine);
thePainter->setPen(aPen);
// Set brush
aBrush.setColor(Qt::black);
aBrush.setStyle(Qt::SolidPattern);
thePainter->setBrush(aBrush);
// Set font
aFont.setFamily("Arial");
aFont.setPixelSize(100); // ??? how to set the font size to 1cm ???
aFont.
setWeight(QFont::Normal);
aFont.setItalic(false);
thePainter->setFont(aFont);
// Draw line
thePainter
->drawLine
(QPoint(1000,
1000),
QPoint(5000,
5000));
// Print a rectangle
thePainter
->drawRect
(QRect(8000,
8000,
2000,
2000));
// Print a text
thePainter->drawText(1000, 12000, aText);
}
Re: Printing with a coordinate system given in millimeters
If you scale the canvas in milimeters, the font size will also have to be given in milimeters but scaled with a factor matching the one between the window and the viewport (in other words you have to calculate how many "pixels" or "points" fit into one "milimeter").
Re: Printing with a coordinate system given in millimeters
HI, I have a quite similar problem, I want to print a square 20 * 20 mm and I'm using this code:
Code:
printer.
setOrientation (QPrinter::Portrait);
int LogicalWidth = 210;
int LogicalHeight = 297;
painter.setWindow(0, 0,LogicalWidth, LogicalHeight);
int PhysicalWidth = printer.width();
int PhysicalHeight = printer.height();
painter.setViewport(0, 0, PhysicalWidth, PhysicalHeight);
painter.begin(&printer);
painter.drawRect(50,50,20,20);
painter.end();
the square I obtain is quite 5*5 mm , but i expect a square 20 * 20 mm...where is my mistake?
Thankyou in advance.
Re: Printing with a coordinate system given in millimeters
This is strange as your example looks correct to me. Maybe "wysota" has an idea.
Re: Printing with a coordinate system given in millimeters
Thanks for reply.
I resolved my problem in this way: taking in account printer resolution (hoping this is a general solution) :
QTransform TPiXEL = QTransform::fromScale(
painter.device()->physicalDpiX() / 25.400,
painter.device()->physicalDpiY() / 25.400);
painter.setWorldTransform(TPiXEL, false);
Thanks.
Re: Printing with a coordinate system given in millimeters
Are you now using setWorldTransform together with setWindow/setViewport or instead of the method suggested by wysota?