April 29, 2012

conny conny
Lab Rat
80 posts

[SOLVED] How to change the background color of selected text in QGraphicsTextItem?

Page  
1

Hi,

I’m looking for a way to change the background color of selected text in QGraphicsTextItem. I’ve tried overriding paint() with the following code. Unfortunately it doesn’ work for me.

  1. void MyTextEditor::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  2. {
  3.     QStyleOptionGraphicsItem* style = const_cast<QStyleOptionGraphicsItem*>(option);
  4.  
  5.     // Remove the HasFocus style state, to prevent the dotted line from being drawn.
  6.     style->state &= ~QStyle::State_HasFocus;
  7.  
  8.     // Setting color does not work
  9.     QPalette p = style->palette;
  10.     p.setColor(QPalette::HighlightedText, QColor("green"));
  11.     p.setColor(QPalette::Highlight, QColor("red"));
  12.     p.setColor(QPalette::Text, QColor("yellow"));
  13.     style->palette = p;
  14.  
  15.     QGraphicsTextItem::paint(painter, style, widget);
  16. }

I’m trying to do this for quite some time already, so I’m happy about all suggestions.

Thanks,
Conny

17 replies

April 29, 2012

Sam Sam
Area 51 Engineer
609 posts

Hi,
Instead of setting the QPalette you can use QPainter->fillRect(), Try the following code:

.h

  1. class MyGraphicsTextItem : public QGraphicsTextItem
  2. {
  3. public:
  4.     MyGraphicsTextItem();
  5.     QRectF boundingRect() const;
  6.     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
  7.  
  8. };

.cpp

  1. QRectF MyGraphicsTextItem::boundingRect() const
  2. {
  3.     return QRectF(0,0,60,30); //set the bounding rect for your text item
  4. }

  1. void MyGraphicsTextItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
  2. {
  3.    
  4.     QStyleOptionGraphicsItem* style = const_cast<QStyleOptionGraphicsItem*>(option);
  5.    
  6.     // Remove the HasFocus style state, to prevent the dotted line from being drawn.
  7.     style->state &= ~QStyle::State_HasFocus;
  8.    
  9.     // Setting color does not work
  10.    
  11.    /* QPalette p = style->palette;
  12.    
  13.     p.setColor(QPalette::HighlightedText, QColor("green"));
  14.     p.setColor(QPalette::Highlight, QColor("red"));
  15.     p.setColor(QPalette::Text, QColor("yellow"));
  16.     style->palette = p;
  17.     */
  18.    
  19.     painter->fillRect(option->rect,Qt::red);
  20.     QGraphicsTextItem::paint(painter, style, widget);
  21.    
  22. }

I commented few lines of your code. Check if this works :)

April 29, 2012

conny conny
Lab Rat
80 posts

Thanks a lot for your reply. Unfortunately this colors the complete background of the text item. What I want is setting the color of the selection only. I’m using this code on Harmattan where the default selection color is a dark blue. Using your code the selection is still blue but the whole background is red.

If you have more tips, I’d be happy to hear them :)

Thanks!
Conny

April 30, 2012

Sam Sam
Area 51 Engineer
609 posts

Sorry I misunderstood the question. It will be helpful if you can attach an image that describes your requirement. Thanks :)

April 30, 2012

conny conny
Lab Rat
80 posts

Sure, I’ve uploaded an image here: Image [twitpic.com]

In words: I want to change the highlight/selection color that a word get marked with if I select it for copy&paste. Well, I think the image makes it clearer :)

May 4, 2012

conny conny
Lab Rat
80 posts

I’ve still found no solution. Does anyone have some more hints?

May 6, 2012

Sam Sam
Area 51 Engineer
609 posts

Hi conny,
One solution can be to override the mousePressEvent() and mouseReleaseEvent() of yourGraphicsTextItem, then create a QRect from the event->pos() and fill the rectangle with the color.

Note: This is just an idea not yet tested!!!!
Regards
Soumitra

May 7, 2012

Wilk Wilk
Ant Farmer
120 posts

Hello
Did you try QGraphicsTextItem::setTextInteractionFlags [qt-project.org] with Qt::TextSelectableByMouse [qt-project.org] as an argument?
Or did I misunderstand what do you want?

May 7, 2012

Sam Sam
Area 51 Engineer
609 posts

Hi Wilk,

The attached image specifies his requirement.

conny wrote:
Sure, I’ve uploaded an image here: Image [twitpic.com]

In words: I want to change the highlight/selection color that a word get marked with if I select it for copy&paste. Well, I think the image makes it clearer :)

May 7, 2012

conny conny
Lab Rat
80 posts

Hi Wilk,

I’ve set those flags and the text is selectable. Only the selection color is always blue and I need to change that color.

Wilk wrote:
Hello Did you try QGraphicsTextItem::setTextInteractionFlags [qt-project.org] with Qt::TextSelectableByMouse [qt-project.org] as an argument? Or did I misunderstand what do you want?

May 7, 2012

conny conny
Lab Rat
80 posts

Hi Soumitra,

that might be an option and I’ll try it. However I fear that painting that rectangle myself will interfere with the painting of the original text selection.

Soumitra wrote:
Hi conny,
One solution can be to override the mousePressEvent() and mouseReleaseEvent() of yourGraphicsTextItem, then create a QRect from the event->pos() and fill the rectangle with the color.

Note: This is just an idea not yet tested!!!!
Regards
Soumitra

May 7, 2012

Wilk Wilk
Ant Farmer
120 posts

Hello again.
If you don’t like blue background color, then look into Qt sources.
You will find out, that background color is selected automaticaly at qt_graphicsItem_highlightSelected method of QGraphicsItem, which is called from paint method of QGraphicsTextItem.
So one of the possible solutions is:

  1. Create class, derived from QGraphicsTextItem.
  2. Override paint method with something like
    1. class YourTextItem : public QGraphicsTextItem {
    2.   //...
    3.   QColor bgcolor;
    4.   //...
    5. }
    6.  
    7. void YourTextItem::paint(QPainter                       *painter,
    8.                          const QStyleOptionGraphicsItem *option,
    9.                          QWidget                        *widget) {
    10.   Q_UNUSED(widget);
    11.   bool is_selected = option->state & (QStyle::State_Selected | QStyle::State_HasFocus);
    12.  
    13.   if (is_selected) {
    14.     option->state &= ~QStyle::State_Selected;
    15.   }
    16.   QGraphicsTextItem::paint(painter,
    17.                            option,
    18.                            widget);
    19.   highlight (painter,
    20.              is_selected);
    21. }
    22.  
    23. void YourTextItem::highlight (QPainter *painter,
    24.                               bool      is_selected) {
    25.   if (is_selected) {
    26.     const qreal itemPenWidth = 1.0;    
    27.     const qreal pad          = itemPenWidth / 2;
    28.  
    29.     const qreal penWidth = 0; // cosmetic pen
    30.  
    31.     const QColor fgcolor = option->palette.windowText().color();
    32.  
    33.     painter->setPen(QPen(bgcolor, penWidth, Qt::SolidLine));
    34.     painter->setBrush(Qt::NoBrush);
    35.     painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
    36.  
    37.     painter->setPen(QPen(option->palette.windowText(), 0, Qt::DashLine));
    38.     painter->setBrush(Qt::NoBrush);
    39.     painter->drawRect(item->boundingRect().adjusted(pad, pad, -pad, -pad));
    40.   }
    41. }

    Try this out, but I didn’t test it.

May 7, 2012

conny conny
Lab Rat
80 posts

Thank you very much for that code. I’ll try it and report back here.

May 11, 2012

conny conny
Lab Rat
80 posts

Hi Wilk,

I found time to look at your code now. Sorry for the delay. Unfortunately all it does is changing the style of the text item itself. It does not change the text selection inside the text item.

However, I’ve followed your advice and read the Qt code until I found out where the styling actually happens. If anyone is interested have a look at:

  • QTextDocumentLayout::draw() and
  • QTextControl::getPaintContext()

To make a long story short, I finally found a way that works. The solution is way easier than I thought and you don’t even have to override anything. Here is the code:

  1. p.setBrush(QPalette::Active, QPalette::Highlight, QBrush(QColor("pink")));
  2. p.setBrush(QPalette::Inactive, QPalette::Highlight, QBrush(QColor("pink")));
  3. p.setBrush(QPalette::Active, QPalette::HighlightedText, QBrush(QColor("green")));
  4. p.setBrush(QPalette::Inactive, QPalette::HighlightedText, QBrush(QColor("green")));
  5. QApplication::setPalette(p, "QTextControl");

Thanks everyone for the help :)

May 11, 2012

Sam Sam
Area 51 Engineer
609 posts

Hi Conny,
Good that you got the solution, and thanks for sharing the code so that we can also use the same. You can edit your first post and add [SOLVED] to the title.

Happy Coding :)

May 11, 2012

conny conny
Lab Rat
80 posts

Already done. Thanks!

Page  
1

  ‹‹ QThread and QObject      A problem constructing objects in a script code ››

You must log in to post a reply. Not a member yet? Register here!