Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Printing and positioning



  • Hello.
    First of all. It seems strange I can't find any question like this one. Seems like I'm missing something obvious.
    Now the problem. For example let's say I need to print a circle with radius of 1/10 of page width in the center of the A4 page. But how do i find where the center is? Sample code below will try to use every available unit (and fails to draw circle properly every time). Perfect solution must work on every system with every printer and with both printer modes. Do I need to use some scale factor?

    #include <QApplication>
    #include <QVBoxLayout>
    #include <QPrintPreviewDialog>
    #include <QPainter>
    #include <QPrinter>
    
    // ---------------------
    // Options (choose one!)
    // ---------------------
    
    #define PRINTER_MODE QPrinter::ScreenResolution
    //#define PRINTER_MODE QPrinter::HighResolution
    
    // ---------------------
    // Print preview dialog
    // ---------------------
    
    class CPrintPreviewDialog: public QPrintPreviewDialog
    {
        Q_OBJECT
    public:
        CPrintPreviewDialog(QPrinter* printer)
            : QPrintPreviewDialog(printer, Q_NULLPTR, Qt::WindowFlags())
        {
            setModal(true);
            connect(this, &CPrintPreviewDialog::paintRequested, this, &CPrintPreviewDialog::onPrint);
        }
    private slots:
        void onPrint(QPrinter* printer)
        {
            QPagedPaintDevice* device = printer;
    
            QPainter painter;
            painter.begin(device);
    
            struct Mode
            {
                QPageLayout::Unit unit;
                QString           name;
            };
            QList<Mode> modes = {
                { QPageLayout::Millimeter, "Millimeter" },
                { QPageLayout::Point     , "Point"      },
                { QPageLayout::Inch      , "Inch"       },
                { QPageLayout::Pica      , "Pica"       },
                { QPageLayout::Didot     , "Didot"      },
                { QPageLayout::Cicero    , "Cicero"     },
            };
    
            QPageLayout layout = device->pageLayout();
    
            for (Mode& mode: modes)
            {
                QRectF pageRect = layout.fullRect(mode.unit);
    
                painter.drawLine(pageRect.topLeft()   , pageRect.bottomRight());
                painter.drawLine(pageRect.bottomLeft(), pageRect.topRight()   );
                painter.drawEllipse(pageRect.center(), pageRect.width()/10, pageRect.width()/10);
                painter.drawText(pageRect.bottomLeft(), "Mode: " + mode.name);
    
                device->newPage();
            }
    
            painter.end();
        }
    };
    
    // ---------------------
    // Main
    // ---------------------
    
    #include "main.moc"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QPrinter* printer = new QPrinter(PRINTER_MODE);
        printer->setPaperSize(QPrinter:: A4);
        printer->setOrientation(QPrinter::Landscape);
    
        CPrintPreviewDialog dlg(printer);
        dlg.show();
    
        return a.exec();
    }
    

  • Moderators

    hi @yuriq
    never used it myself, but shouldn't pageRect give you the needed width&height of your page?

    https://doc.qt.io/qt-5/qprinter.html#pageRect-1



  • @j-hilk said in Printing and positioning:

    never used it myself, but shouldn't pageRect give you the needed width&height of your page?

    I think it should but it doesn't. For every possible unit (mm, point, int etc) size is too small or too big.

    PS I deleted two redundant lines of code in first message.


  • Moderators

    @yuriq well, going a bit further in the documentation

    https://doc.qt.io/qt-5/qprinter.html#pageLayout

    Is what you need ? it contains informations about the margins etc



  • @j-hilk It seems like it is exactly what I need. Actually I use it already. Getting size by paintRect() instead of fullRect() doesn't make difference.

                //QRectF pageRect = layout.fullRect(mode.unit);
                QRectF pageRect = layout.paintRect(mode.unit);
                pageRect.moveTo( layout.margins(mode.unit).left(), layout.margins(mode.unit).top() );
    

    I can get size in millimeters/points etc technically size is correct. But it looks like painter uses internally different units or something like this. It is very confusing.



  • Finally. This code works fine.

        void onPrint(QPrinter* printer)
            {
                QPagedPaintDevice* device = printer;
                QPainter painter;
                painter.begin(device);
        
                int w = device->width();
                int h = device->height();
        
                painter.drawLine(0,0,w,h);
                painter.drawLine(0,h,w,0);
                painter.drawEllipse(QPointF(w/2, h/2), w/10, w/10);
                painter.drawText(0, h, "pixels");
        
                printer->newPage();
        
                painter.end();
            }
    

Log in to reply