PDA

View Full Version : Render QGraphicsScene to a QPrinter to export PDF



tcampos
14th March 2012, 16:57
Hi there,

Ok. Now I am going crazy...

Can anyone tell me why this works:


void Partitura::print()
{
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
QPrintDialog dlg(&printer);
if(dlg.exec()==QDialog::Accepted) {
QPainter p(&printer);
scene->render(&p);
p.end();
}
}

... and this does not work:


void Partitura::exportPDF()
{
QString fileName = QFileDialog::getSaveFileName(this, "Export PDF",
QString(), "*.pdf");
QPrinter printer(QPrinter::HighResolution);
printer.setPageSize(QPrinter::A4);
printer.setOrientation(QPrinter::Portrait);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName(fileName);

QPainter p(&printer);
scene->render(&p);
p.end();
}

scene is a QGraphicsScene object declared as global.
The debugger returns a stack overflow when running the 2nd function.
If i comment the line scene->render(&p); the problem disappears, but obviously i don't get the scene contents on the pdf...

Thanks in advance.
Tiago Campos

tcampos
15th March 2012, 10:35
Please someone, I need help on this issue.

Spitfire
19th March 2012, 09:53
1st - use
tags, it's much easier to read the code.

2nd: this works perfectly fine
[CODE]
void MainWindow::print()
{
QPrinter printer( QPrinter::HighResolution );
printer.setPageSize( QPrinter::A4 );
printer.setOrientation( QPrinter::Portrait );
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( "test.pdf" ); // file will be created in your build directory (where debug/release directories are)

QPainter p;

if( !p.begin( &printer ) )
{
qDebug() << "Error!";
return;
}
this->scene->render( &p );
p.end();
}
One thing i've noticed, for some reason I was not able to save file for example on c:\ (w7).

Create small compilable example of your problem and post it here.

tcampos
19th March 2012, 11:45
Thank you very much for your answer.

I tried exactly the same code you supplied without success.
The QGraphicsScene I'm trying to export to PDF has a large number of objects, including lines, ellipses and QGraphicsSvgItem objects using sharing renderer from QSvgRenderer objects.

Sorry but it is hard to post a small compilable example since the code is now very complex.

I noticed that if I clear the scene with scene->clear(), rendering the scene to the painter works and I'm able to save an empty PDF. So it probably has to do with the the type of objects I am using inside the scene...

Spitfire
20th March 2012, 14:47
If that's the case, then save pdf after adding each item and see which one breaks it.
It may be that single item stops the renderer or may be that you can't render whole family (ie svq items).

tcampos
23rd March 2012, 15:06
That's an excellent idea. Thank you for the tip.

Added after 1 22 minutes:


If that's the case, then save pdf after adding each item and see which one breaks it.
It may be that single item stops the renderer or may be that you can't render whole family (ie svq items).

Hello again.

It seems that the first item added to the scene makes it impossible to export to pdf (a line added with scene->addLine(line, pen)). Before adding it, a pdf is created sucessfully.
Any idea?

The QGraphicsSvgItem objects in the scene are exported to pdf... I don't understand the problem with the lines...

Spitfire
23rd March 2012, 16:24
What are the line points?
What's the pen?

If you coment out this line does every other line causes the same issue?

If yes, can you create very minimal compilable example of the issue for others to test?
I can't see you mentioning what qt version you're using.

tcampos
23rd March 2012, 16:33
I'll do that.

Used pen and example of one of the lines:

QPen pen(Qt::black, 1);
QLineF line(QPoint(0, 140), QPoint(880, 140));

Qt version 4.7.4.

I'm almost sure that every single I try to add to the scene causes this issue.

tcampos
29th March 2012, 15:26
After your suggestions I tried to isolate the problem with the exact same code, restricted to the needed part. To my surprise the program worked correctly. The only difference was that the Ui of the window that contained that graphicsview object was the mainwindow of the program.

In the application I'm developing the window which I'm working in and having that issues is another QMainWindow object that receives the mainwindow by pointer reference. Maybe there is a bug related to it. At least it is what I am supposing...

Anyway I'm not using SVG anymore. I replaced the objects I needed by QPainterPath and QGraphicsPathItem objects relying on fonts (musical symbols from gonville font). Everything works correctly now!

Again, thank you for your help.