Утечка памяти в Qt / C ++ с помощью QThread и QPainter :: drawText () - PullRequest
2 голосов
/ 10 августа 2011

Я использую Qt4.6, 32-битную версию, скомпилированную под 64-битную Linux, и у меня проблема с памятью, которую я не могу понять У меня есть QWidget, содержащий QLabel. Этот QLabel служит областью рисования для каждого параметра перекраски:

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

Изображение обновляется в виджетах paintEvent:

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

То есть рисование выполняется с использованием QThread, где функция с резьбой выглядит следующим образом:

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);
}

Все работает, как и ожидалось, за исключением того, что drawText вызывает серьезные утечки памяти, легко обнаруживаемые после нескольких картин. Проблема появляется только тогда, когда рисование выполнено с использованием потоков и с использованием drawText. Если drawText удален или если он используется напрямую, а не в потоке, в виджетах paintEvent проблем нет. Например, нет проблем в использовании многопоточного рисования с drawLine, drawRect, drawEllipse и т. Д.

Есть ли объяснение этому поведению? И как можно использовать многопоточную функцию drawText без утечек?

1 Ответ

0 голосов
/ 10 августа 2011

Хотя большинство операций рисования поддерживаются на QImage в потоке без графического интерфейса пользователя, в системах X11 supportsThreadedFontRendering определяет, разрешен ли рендеринг текста:

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

Я не уверен, что этот флаг возвращает в вашей системе.Но даже если он говорит "true", тогда в вашей конфигурации может быть достаточно черной магии, чтобы она не работала.

Для некоторых других важных замечаний относительно особенностей обработки Qt потоков и операций рисования смотрите здесь:

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

...