Results 1 to 14 of 14

Thread: [QT4] Printing a dialog

  1. #1
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default [QT4] Printing a dialog

    Looking at the docs, I see that it's relatively easy to print something like a QTextEdit or a QTextBrowser... but what if I want to print a dialog?

    Thus far, I'm not seeing anything to accomplish that .

    Any ideas?
    Life without passion is death in disguise

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: [QT4] Printing a dialog

    Never done that and this is just a guess, but it could work

    Take a "screenshot" (aka. ask to paint itself on a pixmap) of the dialog:
    QPixmap QPixmap::grabWidget ( QWidget * widget, const QRect & rectangle ) [static]

    then just paint the pixmap on the printer, simple huh..?

  3. #3
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Well... trying that, I printed to a postscript file to test with. Ended up with a 1.3M image with just the cancel button of the dialog

    Here's the relevant section of code that I'm currently using:
    Qt Code:
    1. void formMainApp::menuFilePrint()
    2. {
    3. p.setColorMode(QPrinter::GrayScale); //No reason for color in this dialog
    4. p.setCreator("TIRdb");
    5. p.setDocName("TIRdb Printout");
    6. QPrintDialog qp(&p, this);
    7. if(qp.exec() == QDialog::Accepted)
    8. {
    9. QModelIndexList MIL = ui.treeViewSQLList->selectionModel()->selectedIndexes();
    10. QPainter painter;
    11. for(QList<QModelIndex>::iterator i = MIL.begin(); i != MIL.end(); ++i)
    12. {
    13. formTIR * T = TIRTree->findTIR(*i); //TIRTree is my model, findTIR returns the dialog
    14. if(!T) //Some elements in the tree do not have dialogs attached to them
    15. {
    16. continue;
    17. }
    18. QRect rect = painter.viewport();
    19. QPixmap qp = QPixmap::grabWidget(T, rect);
    20. QSize size = qp.size();
    21. size.scale(rect.size(), Qt::KeepAspectRatio);
    22. painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
    23. painter.setWindow(qp.rect());
    24. painter.begin(&p);
    25. painter.drawPixmap(0, 0, qp);
    26. painter.end();
    27. }
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 

    Also, a side note... I'm noticing a decided lack in documentation on just how the print process works (or maybe it's just me). I've looked at QPrinter and I've got to admit that I'm not at all clear on just how it works. Maybe I'm blind; is there a section in the docs that explains this in much greater detail?
    Last edited by KShots; 11th April 2006 at 18:56.
    Life without passion is death in disguise

  4. #4
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Well... I found one bug in the above code. The QRect was an undefined size. I re-sized it to my screen resolution for now (1440x900). This was causing frequent crashes.

    Also caught a childish mistake (surprised the compiler didn't catch it) - qp is both a QPrintDialog and a QPixmap. I have no idea how the compiler was working with that, but I changed the pixmap to qpm...

    With that fixed, I'm still getting large pictures of my cancel button. Any idea what can be causing this?
    Life without passion is death in disguise

  5. #5
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: [QT4] Printing a dialog

    Scale your image to fit the printer with QPixmap::scaled(p.pageRect(), Qt::KeepAspectRatio);
    Save yourself some pain. Learn C++ before learning Qt.

  6. #6
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: [QT4] Printing a dialog

    Quote Originally Posted by KShots
    Also caught a childish mistake (surprised the compiler didn't catch it) - qp is both a QPrintDialog and a QPixmap. I have no idea how the compiler was working with that, but I changed the pixmap to qpm...
    The compiler didn't catch it because it is valid code. You declared the variables in different scopes, so there was no real problem there (although it's good practice to use unique variable names).
    Save yourself some pain. Learn C++ before learning Qt.

  7. #7
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    I guess that kinda makes sense on the qp and qpm variables.

    Scaling the image did just that - scaled the cancel button.

    The problem I'm having is that none of the other widgets in the dialog are shown. All I see is the cancel button. I don't even see the frame around the cancel button.

    Attached is a picture of what I'm getting, and a picture of what I should be getting.
    Attached Images Attached Images
    Last edited by KShots; 12th April 2006 at 19:19.
    Life without passion is death in disguise

  8. #8
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: [QT4] Printing a dialog

    Your call to grabWidget() should be grabWidget(T, T->rect());

    Also, drop the setViewport() and setWindow() stuff.
    Save yourself some pain. Learn C++ before learning Qt.

  9. #9
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Quote Originally Posted by Chicken Blood Machine
    Your call to grabWidget() should be grabWidget(T, T->rect());
    Yeah, that makes a lot more sense
    Quote Originally Posted by Chicken Blood Machine
    Also, drop the setViewport() and setWindow() stuff.
    Done.

    Thus far, nothing is yet changing

    To re-iterate, this is what I have now:
    Qt Code:
    1. void formMainApp::menuFilePrint()
    2. {
    3. p.setColorMode(QPrinter::GrayScale);
    4. //No reason for color in this dialog
    5. p.setCreator("TIRdb");
    6. p.setDocName("TIRdb Printout");
    7. QPrintDialog qp(&p, this);
    8. if(qp.exec() == QDialog::Accepted)
    9. {
    10. QModelIndexList MIL = ui.treeViewSQLList->selectionModel()->selectedIndexes();
    11. QPainter painter;
    12. for(QList<QModelIndex>::iterator i = MIL.begin(); i != MIL.end(); ++i)
    13. {
    14. formTIR * T = TIRTree->findTIR(*i); //TIRTree is my model, findTIR returns the dialog
    15. if(!T) //Some elements in the tree do not have dialogs attached to them
    16. {
    17. continue;
    18. }
    19.  
    20. QPixmap qpm = QPixmap::grabWidget(T, T->rect());
    21. if(qpm.isNull())
    22. {
    23. qDebug() << "Failed to capture the dialog for printing";
    24. return;
    25. }
    26.  
    27. qpm.scaled(p.pageRect().width(), p.pageRect().height(), Qt::KeepAspectRatio);
    28.  
    29. painter.begin(&p);
    30. painter.drawPixmap(0, 0, qpm);
    31. painter.end();
    32. }
    33. }
    34. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by KShots; 12th April 2006 at 20:12.
    Life without passion is death in disguise

  10. #10
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: [QT4] Printing a dialog

    Qt Code:
    1. qpm = qpm.scaled(p.pageRect().width(), p.pageRect().height(), Qt::KeepAspectRatio);
    To copy to clipboard, switch view to plain text mode 
    Save yourself some pain. Learn C++ before learning Qt.

  11. #11
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Ah - I'm kinda embarassed I missed that.

    Still had the same results, but I solved the problem (partially).

    Turns out, you cannot grab a widget that is not being shown. Once I called T->show(), then grabbed the widget, then called T->close(), I got the whole thing.

    For some relatively obvious reasons, I really don't want to have to show the widget(s) just to print them. Also, if I'm going to have a separate thread print the widgets, I really don't want to show them (or rather, I really can't show them). Any other ideas? This will at least make the thing functional, but it won't perform well at all.
    Life without passion is death in disguise

  12. #12
    Join Date
    Jan 2006
    Location
    Mountain View, CA
    Posts
    279
    Thanked 42 Times in 37 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: [QT4] Printing a dialog

    Quote Originally Posted by KShots
    Ah - I'm kinda embarassed I missed that.

    Still had the same results, but I solved the problem (partially).

    Turns out, you cannot grab a widget that is not being shown. Once I called T->show(), then grabbed the widget, then called T->close(), I got the whole thing.

    For some relatively obvious reasons, I really don't want to have to show the widget(s) just to print them. Also, if I'm going to have a separate thread print the widgets, I really don't want to show them (or rather, I really can't show them). Any other ideas? This will at least make the thing functional, but it won't perform well at all.
    Hell, I didn't realize you hadn't shown the widget. Yes, that would explain it. A widget isn't fully laid out until it has been shown at least once.
    Save yourself some pain. Learn C++ before learning Qt.

  13. #13
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Is there a way to lay it out without showing it?
    Life without passion is death in disguise

  14. #14
    Join Date
    Feb 2006
    Location
    USA
    Posts
    142
    Thanks
    24
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: [QT4] Printing a dialog

    Turns out it's another bug. Apparently it will be fixed in 4.1.4.

    In that case, in my app I will work around it (for now) by quickly displaying the dialog, capturing it, and closing it (even if there are hundreds or thousands of them).

    If you're curious, here's the entry in the task tracker
    Life without passion is death in disguise

Similar Threads

  1. Issue with Modelless dialog on Mac
    By Satyanarayana Chebrolu in forum Qt Programming
    Replies: 0
    Last Post: 24th February 2009, 10:10
  2. Replies: 9
    Last Post: 13th August 2008, 18:07
  3. printing QWebView before showing in Dialog
    By Grisu in forum Qt Programming
    Replies: 1
    Last Post: 17th July 2008, 12:20
  4. [QT4] QThread and printing a QList<QPixmap>
    By KShots in forum Qt Programming
    Replies: 3
    Last Post: 24th April 2006, 21:44
  5. dialog box
    By Bahar in forum Qt Programming
    Replies: 3
    Last Post: 31st January 2006, 14:52

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.