Text in a cell with more than one color
-
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)))
{
painter->save();
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 );
painter->restore();
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
- void LrgRunwayCloserStyleItemDelegate::paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
-
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 ); painter->translate(option.rect.topLeft()); doc.drawContents( painter, option.rect.translated(-option.rect.topLeft()) ); painter->restore(); ...
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));
text.setAlignment(Qt::AlignCenter);
text.adjustSize();
options.text = "";
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options,
painter);
painter->translate(options.rect.left(), options.rect.top());
QPoint render_at( option.rect.left(), option.rect.top() );
text.render( painter, render_at );******
- QLabel text(QString("<font color='red'><center><b>%1</b></center></font>").arg(options.text));
-
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; doc.setTextWidth(clipRect.width()); doc.setHtml(html); auto docHeight = doc.documentLayout()->documentSize().height(); auto vOffset = (clipRect.height() - docHeight) / 2; painter->save(); painter->translate(option.rect.left(), option.rect.top() + vOffset); doc.drawContents(painter, clipRect); painter->restore(); }
-
@Chris-Kawa Thank ypu very much for all, the solution is perfect.