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?
Printable View
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?
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..?
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 :confused:
Here's the relevant section of code that I'm currently using:Code:
void formMainApp::menuFilePrint() { QPrinter p; p.setCreator("TIRdb"); p.setDocName("TIRdb Printout"); { QModelIndexList MIL = ui.treeViewSQLList->selectionModel()->selectedIndexes(); QPainter painter; for(QList<QModelIndex>::iterator i = MIL.begin(); i != MIL.end(); ++i) { formTIR * T = TIRTree->findTIR(*i); //TIRTree is my model, findTIR returns the dialog if(!T) //Some elements in the tree do not have dialogs attached to them { continue; } size.scale(rect.size(), Qt::KeepAspectRatio); painter.setViewport(rect.x(), rect.y(), size.width(), size.height()); painter.setWindow(qp.rect()); painter.begin(&p); painter.drawPixmap(0, 0, qp); painter.end(); } } }
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?
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?
Scale your image to fit the printer with QPixmap::scaled(p.pageRect(), Qt::KeepAspectRatio);
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).Quote:
Originally Posted by KShots
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.
Your call to grabWidget() should be grabWidget(T, T->rect());
Also, drop the setViewport() and setWindow() stuff.
Yeah, that makes a lot more senseQuote:
Originally Posted by Chicken Blood Machine
Done.Quote:
Originally Posted by Chicken Blood Machine
Thus far, nothing is yet changing :(
To re-iterate, this is what I have now:Code:
void formMainApp::menuFilePrint() { QPrinter p; //No reason for color in this dialog p.setCreator("TIRdb"); p.setDocName("TIRdb Printout"); { QModelIndexList MIL = ui.treeViewSQLList->selectionModel()->selectedIndexes(); QPainter painter; for(QList<QModelIndex>::iterator i = MIL.begin(); i != MIL.end(); ++i) { formTIR * T = TIRTree->findTIR(*i); //TIRTree is my model, findTIR returns the dialog if(!T) //Some elements in the tree do not have dialogs attached to them { continue; } if(qpm.isNull()) { qDebug() << "Failed to capture the dialog for printing"; return; } qpm.scaled(p.pageRect().width(), p.pageRect().height(), Qt::KeepAspectRatio); painter.begin(&p); painter.drawPixmap(0, 0, qpm); painter.end(); } } }
Code:
qpm = qpm.scaled(p.pageRect().width(), p.pageRect().height(), Qt::KeepAspectRatio);
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.Quote:
Originally Posted by KShots
Is there a way to lay it out without showing it?
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