简体   繁体   中英

Qt/C++ memory leak with QThread and QPainter::drawText()

I'm using Qt4.6, 32bit compiled under 64bit Linux, and have a puzzling memory problem which I can't figure out. I have a QWidget containing a QLabel. This QLabel serves as a painting area by for each repaint setting:

m_label->setPixmap(QPixmap::fromImage(image));

The image is updated in the widgets paintEvent:

void MemTest::paintEvent(QPaintEvent* pEvent)
{
    // Wait for latest painting if not finished, then perform threaded repaint
    m_plotThread->wait();
    m_plotThread->start();
}

That is, the painting is performed threaded using a QThread, where the threaded function looks like this:

void PlotThread::run()
{
    // Lock the thread
    m_mutex.lock();

    // Image for painting
    QImage image(400, 300, QImage::Format_ARGB32);
    image.fill(0);

    // Create painter on the image
    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QFont font("Helvetica", m_textSize);
    painter.setFont(font);
    painter.setPen(QColor(255,0,0));
    painter.setBrush(QColor(130,150,255));

    // Draw some shapes
    painter.drawLine(0, 0, 400, 300);
    painter.setPen(QColor(40,30,30));
    painter.drawEllipse(15, 50, 130, 90);

    // Draw the text
    // !!! This causes memory leak !!!
    painter.drawText(QPoint(40, 100), "What's my problem?");

    m_mutex.unlock();

    // Send painted image through signal
    emit plotFinished(image);
}

Everything works as expected, except that the drawText causes severe memory leaks, easily detected after multiple paintings. The problem only appears when the painting is done threaded and using drawText. If the drawText is removed or if it's used directly, not threaded, in the widgets paintEvent there's no problem. There is for example no problems in using multi-threaded painting with drawLine, drawRect, drawEllipse etc.

Is there an explanation for this behavior? And how can the drawText function be used multi-threaded without causing leaks?

While most drawing operations are supported onto QImage in a non-GUI thread, there is a supportsThreadedFontRendering on X11 systems about whether text rendering is allowed:

http://doc.qt.nokia.com/4.7-snapshot/qfontdatabase.html#supportsThreadedFontRendering

I'm not sure what that flag is returning on your system. But even if it said "true" then there might be enough black magic in your configuration that it won't work.

For some other important notes on the specifics of Qt's handling of threading and paint operations, look here:

http://doc.qt.nokia.com/4.7-snapshot/threads-modules.html#painting-in-threads

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM