I'm using QThread
for printing work via QPrinter
My PrintWorker
look like this :
class PrintWorker : public QObject {
Q_OBJECT
public:
PrintWorker(QThread*, QPrinter*, QPicture*, QPainter*, QObject *parent = 0);
private:
QPicture *_picture = nullptr;
QPrinter *_printer = nullptr;
QPainter *_painter = nullptr;
public slots:
void print();
signals:
void done();
};
PrintWorker::PrintWorker(QThread *thread, QPrinter *printer, QPicture *picture, QPainter *painter, QObject *parent) :QObject(parent),
_picture(picture), _printer(printer), _painter(painter)
{
moveToThread(thread);
QObject::connect(thread, &QThread::started, this, &PrintWorker::print);
QObject::connect(this, &PrintWorker::done, thread, &QThread::quit);
QObject::connect(this, &PrintWorker::done, this, &PrintWorker::deleteLater);
QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);
}
void PrintWorker::print() {
// do some print job with painter and picture
emit done();
}
And print
Method is this :
void NewService::print() {
if (!_printer) { /* _printer : a private member */
_printer = new QPrinter(QPrinter::HighResolution);
_printer->setPageSize(QPrinter::A5);
_printer->setPageOrientation(QPageLayout::Portrait);
_printer->setColorMode(QPrinter::Color);
}
if (!_printDialog) { /* _printDialog : a private member */
_printDialog = new QPrintDialog(_printer);
}
if (_printDialog->exec() == QPrintDialog::Accepted) {
MyWidget *widget = new MyWidget(/* some args*/);
QPainter *painter = new QPainter;
QPicture *picture = new QPicture;
widget->render(picture);
QThread *thread = new QThread;
PrintWorker *worker = new PrintWorker(thread, _printer, picture, painter);
thread->start();
}
}
Now before invoking print()
my app exposes about 9MB of memory after printing and invoking PrintWorker::print()
my app's memory usage get to 26MB
In Another world if we remove emit done
at last part in PrintWorker::print()
it makes no difference.
What we expect after finishing job is memory usage should get down to 26MB - Thread space + _printer
+ _printDialog
objects size ≈ 14MB
So What's wrong with this ?
You are deleting PrintWorker
and QThread
objects, but not QPainter
, QPicture
, MyWidget
, QPrintDialog
nor QPrinter
. Those are memory leaks ( new
with no delete
). Note that PrintWorker
destructor could take care of deleting QPainter
, QPicture
and QPrinter
, additionnaly, it could also take ownership of MyWidget
and delete it. Hopefully QPrintDialog
object is deleted by NewService
class, but it's hard to say as code was not posted.
Also, as recommende by rafael gonzalez, you should check that QThread
PrintWorker
and QThread
are actually being deleted.
By the way, how did you check memory usage? Through a leak detection tool (like valgrind, VLD...)? Or through Windows Task Manager. Because task manager is definitely unaccurate.
By calling QThread::quit()
you are activly exiting the EventLoop in this thread. A QObject::deleteLater()
for objects residing in this thread may not be executed anymore (though they mention on QThread::finished()
-signal the delete later slot will still be called).
I personally would just set up the connection using the finished()
signal or set the parent of the worker-object to be the thread itself, then Qt actually has to remove the object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.