[Interest] Subclassing QStyledItemDelegate to implement multi-color text in a single QTableView cell/item?

Girish Ramakrishnan girish at forwardbias.in
Thu Apr 12 18:09:23 CEST 2012


On Wed, Apr 11, 2012 at 11:41 AM, Carl Schumann <schumann at fnal.gov> wrote:
> Qt community,
>
> I am trying to use Qt to replace an old program that uses multi-color
> text strings within a single spreadsheet cell in its user interface.
> With Qt 4.5 I had success by subclassing QStyledItemDelegate.   With Qt
> 4.8 I found that the text did not appear entirely within cell and was
> cropped at the edges of the cell.   My kludge work around was to add
> rather aribitary constants to the position passed to the render member
> function.    Can anyone shed some light on what I am doing wrong here
> please?   Thanks for any help.
>
> Sincerely,
> Carl Schumann
>
> My paint method indirectly is as follows:
>> void SheetModel::AclRow::paint( QPainter * painter, const
>> QStyleOptionViewItem & option, const QModelIndex & index,
>> SheetModelItemDelegate const * delegate ) const
>> {
>>     int column = index.column();
>>     if( column == SheetModel::AclRow::COLUMN_COMMAND ){
>>         painter->save();
>>         QLabel text( "<font color=\"" + Colors.YELLOW.name() + "\">" +
>> ACL_PREFIX + "</font> <font color=\"" + Colors.CYAN.name() + "\">" +
>> this->command + "</font>" );
>>         QPalette pal = text.palette();
>>         pal.setColor(QPalette::Window, Colors.BLACK);
>>         text.setPalette(pal);
>>         text.setAutoFillBackground(true);
>>         text.adjustSize();
>> #define QT_4_8_0 1
>> #if QT_4_8_0
>>
>>         int top_bottom = option.rect.bottom() + 4;
>>         int left_right = option.rect.left() + 30;
>>         QPoint render_at( left_right, top_bottom );
>> #else
>>         int top  = option.rect.top() + (option.rect.height() -
>> text.height()) / 2; // center text in cell vertically
>>         int left = option.rect.left() + text.height() / 3; // indent a
>> third of the height - this is somewhat arbitary
>>         QPoint render_at( left, top );
>> #endif
>>         painter->fillRect( option.rect, Colors.BLACK );
>>         text.render( painter, render_at );
>>         painter->restore();
>>     } else {
>>         // All other columns use the default behavior inherited from
>> the superclass
>>         this->Row::paint( painter, option, index, delegate );
>>     }
>>     return;
>> }
>

I don't think this reply with answer your question directly, but here
are some questions/tips.
1. Check the size hints returned by the delegate for the index. Does
it take into account all the offset that you are doing when actually
painting?
2. The painting itself can be implemented better by using
QTextDocument instead of the QLabel.
3. The paint code should check if there is enough space to draw text.
And if not should elide the text.

Girish



More information about the Interest mailing list