Results 1 to 6 of 6

Thread: Print preview of a QWidget

  1. #1
    Join Date
    Nov 2013
    Location
    Kungsbacka, Sweden
    Posts
    13
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Print preview of a QWidget

    Hi,

    My goal is to create a print preview function which allows users to see the crossword they've created as it would appear on a piece of paper. Reading the documentation I thought this would be a piece of cake. Here's what I've got so far (taken from the documentation describing how to print a widget):

    Qt Code:
    1. void MyWindow::filePrintPreview()
    2. {
    3. QPrinter printer;
    4. QPainter painter;
    5. painter.begin(&printer);
    6. double xscale = printer.pageRect().width()/double(cwArea->width());
    7. double yscale = printer.pageRect().height()/double(cwArea->height());
    8. double scale = qMin(xscale, yscale);
    9. painter.translate(printer.paperRect().x() + printer.pageRect().width()/2,
    10. printer.paperRect().y() + printer.pageRect().height()/2);
    11. painter.scale(scale, scale);
    12. painter.translate(-width()/2, -height()/2);
    13. cwArea->render(&painter);
    14. QPrintPreviewDialog preview(&printer, this);
    15. connect(&preview, SIGNAL(paintRequested(QPrinter*)), SLOT(print(QPrinter*)));
    16. preview.exec();
    17. }
    To copy to clipboard, switch view to plain text mode 

    MyWindow is my QMainWindow and filePrintPreview() is the slot called when "file->print preview" is triggered.
    cwArea is the widget containing the crossword squares.

    I read that if I want to render the contents of a widget, these contents have to be children of the widget itself. Since each crossword square is an overridden QTextEdit I added an optional parent parameter to each of the constructors...

    Qt Code:
    1. Tile::Tile(..., QWidget *parent)
    2. {
    3. (...)
    4. }
    To copy to clipboard, switch view to plain text mode 

    ...and let the crossword widget be each square's parent. For example:

    Qt Code:
    1. for(int i = 0; i < rows; i++)
    2. {
    3. for(int j = 0; j < columns; j++)
    4. {
    5. cwlayout->addWidget(new Tile(...,this),i*4,j*4,4,4);
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 

    Unfortunately all I've managed to preview so far is absolutely nothing.
    What have I done wrong? Is it a problem when the child widgets of the widget I wish to print are QTextEdits?

    Thanks in advance!

  2. The following user says thank you to Ponnytail for this useful post:


  3. #2
    Join Date
    Nov 2013
    Location
    Kungsbacka, Sweden
    Posts
    13
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Print preview of a QWidget

    Something strange happened today. I connected myself to a wireless network with a printer and suddenly 3 documents I had forgotten to remove from my print queue got printed out. All 3 of them showed the template crossword I had created for testing purposes, scaled pretty badly though. So my question would rather be, why can I print my widget but not print preview it?

    Edit:
    I should have provided this earlier. Requesting a print preview actually causes errors which should explain the empty print preview window.

    Qt Code:
    1. QPainter::begin(): Returned false
    2. QPainter::translate: Painter not active
    3. QPainter::scale: Painter not active
    4. QPainter::translate: Painter not active
    5. QWidget::render: Cannot render with an inactive painter
    To copy to clipboard, switch view to plain text mode 

    I can't tell why the begin function returns false. The documentation said I could use a QPainter constructor instead of calling begin() but this produces exactly the same errors. I have searched for clues but so far without success. Any help would be appreciated.

    Thanks in advance!
    Last edited by Ponnytail; 4th December 2013 at 14:03.

  4. The following user says thank you to Ponnytail for this useful post:


  5. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Print preview of a QWidget

    The code from line 4 to 13 belongs in the slot you connected to the paintRequested() signal from the preview widget. Line 3 need not exist. When the preview widget is exec() it will emit the paintRequested() signal telling you what printer device to paint on: you should paint on it. This printer device will be redirected by the preview widget to the screen. You can use the same slot to service a print immediately function by simply passing a real QPrinter.

    Your existing code prints to the system default printer every time it is called and ignores the preview.

  6. The following user says thank you to ChrisW67 for this useful post:

    Ponnytail (4th December 2013)

  7. #4
    Join Date
    Nov 2013
    Location
    Kungsbacka, Sweden
    Posts
    13
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Print preview of a QWidget

    Oh that explains why an empty preview window was shown and a print requested. I got my slots from an example of print preview. They are filePrintPreview(), filePrint() and print(QPrinter *printer). I simply thought the print slot had nothing to do with the preview and ignored its connect. Your answer is perfect. Moving the lines makes it possible to preview the widget. Thanks a lot for the help, Chris!

    A last curiosity though. I read that a QPainter is almost always created inside a paintEvent() and I guess this is why I couldn't create one inside my filePrintPreview() slot. Why can I create a QPainter inside the print(...) slot? This is also outside paintEvent() right? I understand I request painting but shouldn't the widget's paintEvent() handle such requests?

  8. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Print preview of a QWidget

    You can create and use a QPainter to paint on any QPaintDevice. All QWidgets are QPaintDevices so by far the majority of painting is done in QWidget::paintEvent() to render your UI. Other QPaintDevices include QPixmap, QImage, and QPrinter can be used outside the painting code for a widget.

  9. #6
    Join Date
    Nov 2013
    Location
    Kungsbacka, Sweden
    Posts
    13
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Print preview of a QWidget

    Ah, alright! Thanks for the clarification

Similar Threads

  1. pyqt print preview QTableView
    By iraj_jelo in forum Qt Programming
    Replies: 0
    Last Post: 23rd May 2012, 08:44
  2. Print preview on QGraphicsItem
    By lni in forum Qt Programming
    Replies: 0
    Last Post: 13th April 2012, 05:25
  3. Print preview for Qt activex
    By sowmya in forum Qt Programming
    Replies: 0
    Last Post: 19th July 2010, 10:53
  4. print preview
    By wbt_ph in forum Qt Programming
    Replies: 4
    Last Post: 1st August 2009, 06:41
  5. Cancelling Long-running Print/Print Preview
    By ChrisW67 in forum Newbie
    Replies: 4
    Last Post: 16th June 2009, 23:05

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.