Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Printing and positioning

Printing and positioning

Scheduled Pinned Locked Moved Solved General and Desktop
printingscaling
6 Posts 2 Posters 1.3k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Y Offline
    Y Offline
    YuriQ
    wrote on last edited by YuriQ
    #1

    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();
    }
    
    J.HilkJ 1 Reply Last reply
    0
    • Y YuriQ

      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();
      }
      
      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      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


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • Y Offline
        Y Offline
        YuriQ
        wrote on last edited by
        #3

        @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.

        J.HilkJ 1 Reply Last reply
        0
        • Y YuriQ

          @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.

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #4

          @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


          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          Y 1 Reply Last reply
          0
          • J.HilkJ J.Hilk

            @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

            Y Offline
            Y Offline
            YuriQ
            wrote on last edited by YuriQ
            #5

            @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.

            1 Reply Last reply
            0
            • Y Offline
              Y Offline
              YuriQ
              wrote on last edited by
              #6

              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();
                      }
              
              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved