Search code examples
qthighlightqgraphicsitemtextcolor

Change highlight color of text inside a QGraphicsTextItem


I would like to change the highlight color of the selected text inside a QGraphicsTextItem.

I have the paint method subclassed, so I thought it can be as simple as setting a different palette on the QStyleOptionGraphicsItem - but I can't see any examples, and what I try is not working:

void TextItem::paint(QPainter* painter,
                     const QStyleOptionGraphicsItem* option,
                     QWidget* widget)
{
    QStyleOptionGraphicsItem opt(*option);

    opt.palette.setColor(QPalette::HighlightedText, Qt::green);

    QGraphicsTextItem::paint(painter, &opt, widget);
}

This has no effect....

How can I change the highlight color of the selected text inside an item ?


Solution

  • The default implementation of QGraphicsTextItem::paint() doesn't care about QStyleOptionGraphicsItem::palette. You have to implement a custom painting if you want different color.

    This is a simplified way how to do it:

    class CMyTextItem : public QGraphicsTextItem
    {
      public:
        virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
        {      
          QAbstractTextDocumentLayout::PaintContext ctx;
          if (option->state & QStyle::State_HasFocus)
            ctx.cursorPosition = textCursor().position();
    
          if (textCursor().hasSelection()) 
          {
            QAbstractTextDocumentLayout::Selection selection;
            selection.cursor = textCursor();
    
            // Set the color.
            QPalette::ColorGroup cg = option->state & QStyle::State_HasFocus ? QPalette::Active : QPalette::Inactive;
            selection.format.setBackground(option->state & QStyle::State_HasFocus ? Qt::cyan : ctx.palette.brush(cg, QPalette::Highlight));
            selection.format.setForeground(option->state & QStyle::State_HasFocus ? Qt::blue : ctx.palette.brush(cg, QPalette::HighlightedText));
    
            ctx.selections.append(selection);       
          }      
    
          ctx.clip = option->exposedRect;
          document()->documentLayout()->draw(painter, ctx);
    
          if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
            highlightSelected(this, painter, option);
        }
    };
    

    However, this solution is not perfect. Not-blinking text cursor is one imperfection. There are probably others. But I believe that improving it a little will be not that big deal for you.