passing a QPainter object to widgets
Hello,
I'm writing a program that acts this way:
- I have a principal QWidget over which I create a QPainter,
- I draw on the widget,
- I pass the Painter to other widgets so I can use those widgets to draw on the principal one,
- Finally,in the principal widget,I call end() on the painter.
The program works properly but ends with a segmentation fault. I runned gdb and it sais that the problem was that it doesn't found qlist.h (quite strange I think).
However the output has no apparent problem:I can display the result of my painting on video and I can eventually draw it on a file. The problem arises when I try to convert the .ps image created with my program to a .pdf,in fact I obtain this error using dvipdf ( in fact I use the .ps file I create as an image in a latex text):
/usr/bin/dvipdf: line 40: 20896 Broken pipe exec dvips -q -f "$infile"
20897 Segmentation fault | gs $OPTIONS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
I'm sure it's not a problem of the latex file or of my dvipdf because if I do the same things but without passing the QPainter to other widgets,I have no problem.
What can I do?
thanks!
Re: passing a QPainter object to widgets
Hi,
You can try to do something like
Code:
// Principal widget
void ChildWidget
::myFunc(QPainter* painter
) {
painter->begin(parentWidget());
// Drawing
painter->end();
}
PS. If you use Qt 4.1 you can print to a PDF file directly using
Code:
printer.
setPrinterMode(QPrinter::HighResolution);
printer.
setOutputFormat(QPrinter::PdfFormat);
PPS. Sorry for my very bad English.
PPPS. For vratojr: I'm italian like you. If you like you can write me in private post in Italian
Re: passing a QPainter object to widgets
Quote:
Originally Posted by vratojr
- I draw on the widget,
- I pass the Painter to other widgets so I can use those widgets to draw on the principal one,
QCanvas does similar thing, so there shouldn't be any problems with this approach.
How do those widget draw themselves?
Quote:
Originally Posted by vratojr
The program works properly but ends with a segmentation fault. I runned gdb and it sais that the problem was that it doesn't found qlist.h (quite strange I think).
Make sure you compile your application in debug mode (you should have "CONFIG += debug" in .pro file). Then run your application from gdb. When is crashes issue "bt" command to print the backtrace and post it here.
Re: passing a QPainter object to widgets
Quote:
How do those widget draw themselves?
Here is a brief description:
Code:
//Inside the Main widget's paintEvent:
painter.begin( graficoPaintDevice );
//drawing
assex = new AsseNumerico (/*options*/,painter,this);
assex.draw();
painter.end();
//stucture of the second widget
public:
AsseNumerico(....);
private:
};
void AsseNumerico::draw(Qpainter &painter){
p.drawSomething();
}
Quote:
Make sure you compile your application in debug mode (you should have "CONFIG += debug" in .pro file). Then run your application from gdb. When is crashes issue "bt" command to print the backtrace and post it here.
Well, first. I will explain better and briefly how the program works. I do some calculation to draw an istogram on screen and afterward I give the opportunity to print it.
If I display the istogram on screen WITHOUT trying to print it I got the the error:
*** glibc detected *** double free or corruption (!prev): 0x0825f648 ***
And, if i use the file in the .ps and then use dvipdf I got the error:
/usr/bin/dvipdf: line 40: 28347 Broken pipe exec dvips -q -f "$infile"
28348 Segmentation fault | gs $OPTIONS -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile="$outfile" $OPTIONS -c .setpdfwrite -
Segmentation fault
And this is the ouput from gdb:
*** glibc detected *** double free or corruption (!prev): 0x08252e38 ***
Program received signal SIGABRT, Aborted.
[Switching to Thread -1221314880 (LWP 31932)]
0xffffe410 in ?? ()
(gdb) bt
#0 0xffffe410 in ?? ()
#1 0xbfffed94 in ?? ()
#2 0x00000006 in ?? ()
#3 0x00007cbc in ?? ()
#4 0xb738c6e5 in raise () from /lib/tls/libc.so.6
#5 0xb738e049 in abort () from /lib/tls/libc.so.6
#6 0xb73c07ba in __fsetlocking () from /lib/tls/libc.so.6
#7 0xb73c6d9c in malloc_trim () from /lib/tls/libc.so.6
#8 0xb73c737a in free () from /lib/tls/libc.so.6
#9 0xb756a6f1 in operator delete () from /usr/lib/libstdc++.so.6
#10 0xb7bca5d7 in ~QPainterPrivate (this=0x82644b0) at qpainter_p.h:120
#11 0xb7bbe78a in ~QPainter (this=0x819629c) at painting/qpainter.cpp:635
#12 0x08081a4b in ~AsseRiferimento (this=0x8196238) at .moc/moc_assenumerico.cpp:77
Re: passing a QPainter object to widgets
Quote:
Originally Posted by vratojr
*** glibc detected *** double free or corruption (!prev): 0x08252e38 ***
Program received signal SIGABRT, Aborted.
[...]
#12 0x08081a4b in ~AsseRiferimento (this=0x8196238) at .moc/moc_assenumerico.cpp:77
It seems that you delete memory twice. What happens in that AsseRiferimento destructor?
Re: passing a QPainter object to widgets
Quote:
Originally Posted by vratojr
Here is a brief description:
Code:
//Inside the Main widget's paintEvent:
painter.begin( graficoPaintDevice );
//drawing
assex = new AsseNumerico (/*options*/,painter,this);
assex.draw();
painter.end();
//stucture of the second widget
public:
AsseNumerico(....);
private:
};
void AsseNumerico::draw(Qpainter &painter){
p.drawSomething();
}
Try to use QPainter pointer as function parameter instead o reference
Using copy constructor you force the creation of a copy object and destruction of it. Passing pointer you don't.
Re: passing a QPainter object to widgets
Code:
It seems that you delete memory twice. What happens in that AsseRiferimento destructor?
Nothing.
I didn't wrote code for the destructor.
should I?
Re: passing a QPainter object to widgets
Quote:
Originally Posted by vratojr
Nothing.
I didn't wrote code for the destructor.
should I?
No, you don't have to write it. So the problem is probably because you create a copy that QPainter. Try what mcosta suggests.
Re: passing a QPainter object to widgets
Quote:
Originally Posted by jacek
So the problem is probably because you create a copy that QPainter.
Qt Official Documentation says
Quote:
QPainter::QPainter ( QPaintDevice * pd )
Constructs a painter that begins painting the paint device pd immediately.
This constructor is convenient for short-lived painters, e.g. in a paint event and should be used only once.
The constructor calls begin() for you and the QPainter destructor automatically calls end().
So, you must use QPainter pointer.
Re: passing a QPainter object to widgets
You were right, I resolved doing that way.
Thank you very much boys!