Qt app freeze when remove usb drive while qpainter is drwaing
-
painter = new QPainter();
printer = new QPrinter();
printer->setOutputFormat(QPrinter::PdfFormat);
printer->setFullPage(true);
printer->setResolution(60);
printer->setOrientation(QPrinter::Portrait);
printer->setPaperSize(QPrinter::A3);
// /media/sda1/EventLog.pdf
printer->setOutputFileName(destLog+filename+".pdf");
painter->begin(printer);Note: painter & printer are class member variable
On usb device remove signal we try to call following at which app freeze
painter->end();If we skip above end() call and try to print next time following error thrown:
11.26 06:42:28.681 WRN DEV: :0 --> QPrinter::setOutputFileName: Cannot be changed while printer is active
11.26 06:42:28.682 WRN DEV: :0 --> QPainter::begin: A paint device can only be painted by one painter at a time.Can you suggest how we can handle usb device removed while painting is in progress?
qt 5.9.4 is used
-
Hi and welcome to devnet,
Are you properly deleting your painter and printer objects ? From the looks of it you are currently leaking them.
These class are usually instanciated on the stack and not the heap.
-
@SGaist How we can delete qprinter object? I have called painter->end() call usb stick is removed but after looking logs when we call painter->end() methods process freeze.
PS O/P:
root 1133 3.0 0.0 0 0 ? Zl 22:24 0:08 [MyApp] <defunct>Since we pass QPrinter as device to Qpainter and QPrinter output file path is set on usb device location which will be unavailable after removing usb stick, may be that's why paint->end() call failed becoz of resource unavailable
-
@Vijay-R-Gawade said in Qt app freeze when remove usb drive while qpainter is drwaing:
How we can delete qprinter object?
Like any other object allocated via new:
delete printer;
But as @SGaist pointed out there is no need to allocated on the heap via new, just allocate on the stack:
QPainter painter;
-
@Vijay-R-Gawade Why don't you simply allocate them on the stack? Stack allocation is way faster than heap and you do not have to bother to delete the stuff again.
Can you show your current code?
-
ReportGenerator::ReportGenerator(QObject *parent) : QObject(parent) { pdfTimer = new QTimer(); pdfTimer->setInterval(200); connect(pdfTimer, SIGNAL(timeout()), this, SLOT(startPDFTimer())); painter = new QPainter(); printer = new QPrinter(); printer->setOutputFormat(QPrinter::PdfFormat); printer->setFullPage(true); printer->setResolution(60); printer->setOrientation(QPrinter::Portrait); printer->setPaperSize(QPrinter::A3); } void ReportGenerator::pdfReport() { // reinitialize painter & printer same as in constr when deleting obj in case of usb remove in startPDFTimer() func printer->setOutputFileName(filename + ".pdf"); //media/sda1/EventLog.pdf painter->begin(printer); // drwaing some header using painter pdfTimer->Start() } void ReportGenerator::startPDFTimer() { // Read records from DB // And draw using painter // Note: rm->usbIsReady: have state usb device connected or not if (!globalQuery.next()) { pdfTimer->stop(); painter->end(); emit reportGenerated(); } else { // USB removed while some more records remaining if (!rm->usbIsReady()) { pdfTimer->stop(); //delete painter; //delete printer; painter->end(); emit showErrorPopup() } } }
-
This post is deleted!
-
What is the logic behind using that timer ?
You might also want to consider QPdfWriter.
-
@SGaist Timer is used to add some delay to Update Progress bar on UI by one step when each record from DB is drawn.
Right now I'm sure problem with paint->end() library call when usb stick is removed.
So I changed the O/P file path to Device temp dir and when all done copy it to usb device. And in case of usb-stick is removed at middle, paint->end() will call as normal (not crashing since Device Temp path available always) -
@Vijay-R-Gawade said in Qt app freeze when remove usb drive while qpainter is drwaing:
@SGaist Timer is used to add some delay to Update Progress bar on UI by one step when each record from DB is drawn.
That's a fishy procedure to update your progress bar.