Qt World Summit: Submit your Presentation

HTML rendering in QStyledItemDelegate sub-class

  • I need html rendering in a custom item delegate. What i have already done

    Write it using QTextDocument, setHtml and QTextDocument::draw.

    Split QTextDocument into blocks using QTextDocument::begin() and draw each block using QTextBlock::charFormat() to setup the QPainter.

    Why the dont work:

    Solution 1, it works, but since there is no text-overflow css property, I can't use ellipsis for long lines.

    Solution 2, it also works, and i can manually use QFontMetrics::elidedText() so this solution is better but, the QTextCharFormat has wrong font information "althought the foreground and background colors are correct", for instance I used the <b></b> tag, so it should be bold but it isn't .

    Here is relevant code for the second solution, thank you for your help in advance.

    @static void
    textDocumentDrawContents(QPainter *painter, const QTextDocument *document,
    int width, bool selected, const QPalette &palette)
    QTextBlock it;
    QAbstractTextDocumentLayout *layout;

    if ((painter == NULL) || (document == NULL))
    layout = document->documentLayout();
    if (layout == NULL)
    QVector<QTextFormat> formats(document->allFormats());
    for (it = document->begin() ; it != document->end() ; it = it.next())
        int           index;
        const QRectF &rectangle(layout->blockBoundingRect(it));
        index = it.charFormatIndex();
        if ((index < 0) || (index >= formats.count()))
        QTextFormat textformat(formats.at(index));
        if (textformat.isCharFormat() == false)
        QString         text;
        QTextCharFormat format(textformat.toCharFormat());
        const QBrush   &foreground(format.foreground());
        const QFont    &font(format.font());
        QFontMetrics    metrics(font);
        text = metrics.elidedText(it.text(), Qt::ElideRight, width - 8);
        if (selected == true)
        painter->drawText(rectangle, text);


    renderHtml(QPainter *painter, const QStyleOptionViewItem &option, QTextDocument *document)
    const QRect &frame(option.rect);
    bool selected;
    bool active;

    if (painter == NULL)
    selected  = ((option.state & QStyle::State_Selected) == QStyle::State_Selected);
    active    = ((option.state & QStyle::State_Active) == QStyle::State_Active);
    selected  = ((selected == true) && (active == true));
    painter->translate(frame.left(), frame.top()); 
    textDocumentDrawContents(painter, document, frame.width(), selected, option.palette);


  • Oh by the way. I am aware of QWebView, but I want a QWebViewLESS solution.

Log in to reply