Qt World Summit: Register Today!

Text in a cell with more than one color

  • I want to show a rich text (<b>18R - <7b> <red> 18L </red>) in a cell of a table view. Which is the best way to do this?

    Do you have some example about this?

    Thank you,

  • Moderators

    You can create a custom QStyledItemDelegate and override the paint(...) method. Inside it you can use QTextDocument to format and paint the content however you need.

  • Thank you. I have already done it but I haven't seen any letter.
    I show my code:

    • void LrgRunwayCloserStyleItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
      if((index.row() == 3) || ((index.row() == 4)))
      const QString runways = index.model()->data(index, Qt::DisplayRole ).toString();
      // Use any qt-supported html tags
      const QString html = QString( "<html style='color:#ff0000;'>%1</html>" ).arg( runways );
      QTextDocument doc;
      doc.setHtml( html );
      QRectF rc( option.rect );
      doc.drawContents( painter, rc );
      QStyledItemDelegate::paint(painter, option, index);

  • Moderators

    Yeah, it's a little counterintuitive, but the document is painted in the painter coords, not the clipping rectangle coords. To be more specific - no matter what the clipping rectangle is the document will paint starting in the upper left corner of the table (not the cell) and then be clipped to the cell rectangle.
    So to fix this you need to shift the painter coords and the clip rectangle coords to match these of the text document:

    doc.setHtml( html );
    doc.drawContents( painter, option.rect.translated(-option.rect.topLeft()) );

    Btw. you don't have to go through the model to get data. You can get it directly from the index:

    const QString runways = index.data(Qt::DisplayRole).toString();

  • @Chris-Kawa Ok thank you very much, I solve the problem, but I have another problem because I don't get to put the text center in the cell, is this possible?
    Instead of QDocumnet, is It possible to paint a QLabel? How?

    Thank You.

  • I put this code to QLabel but paint nothing

    • QLabel text(QString("<font color='red'><center><b>%1</b></center></font>").arg(options.text));
      options.text = "";
      options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options,
      painter->translate(options.rect.left(), options.rect.top());
      QPoint render_at( option.rect.left(), option.rect.top() );
      text.render( painter, render_at );******

  • Moderators

    Sorry but this code makes little sense and creating a label to paint some text seems like an overkill.

    Here is an example that will center your text both horizontally and vertically

    void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
        QRect clipRect(0,0,option.rect.width(), option.rect.height());
        auto text = index.data(Qt::DisplayRole).toString();
        auto html = QString("<p align=center style='color:#ff0000;'>%1</p>").arg(text);
        QTextDocument doc;
        auto docHeight =  doc.documentLayout()->documentSize().height();
        auto vOffset = (clipRect.height() - docHeight) / 2;
        painter->translate(option.rect.left(), option.rect.top() + vOffset);
        doc.drawContents(painter, clipRect);

  • @Chris-Kawa Thank ypu very much for all, the solution is perfect.

Log in to reply