Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QPainter colored text (syntax coloring)

I have a custom Qt widget which I used to display disassembly and I am looking to add syntax coloring to it.

Currently, I simply set the QPen to a solid color, construct the text I want to display, and render it to the QPainter at the appropriate coordinates.

The question is, what is the best approach to adding syntax coloring? I've thought of a few:

  1. I could simply divide the coloring into logical blocks, each preceded by setting the QPen to the desired color.
  2. I could have special escape characters which represent a change in the color palette, and render 1 character at a time.
  3. I could do a modification of #1 and create a list of std::pair<QColor, QString>, then I could simply iterate the list setting the color and drawing the text as I pop items off the front of the list.
  4. Something entirely different?

I know that each of the 3 approaches I've listed will technically work, but I'm looking for a very efficient solution. This code will be called a lot. And since this is an interactive debugger, if this code is slow, someone rapidly stepping or tracing will see a visible slowdown.

EDIT: I'm aware of QSyntaxHighlighter and QTextDocument. The main issue is that these don't generally suite my purposes very well. I have several columns which all have dividers and can be slid back and forth. To give you an idea, Here's a link to a screenshot of my debugger. As you can see it isn't really like a text document at all. In fact it is closer to a list or table. But there is already a bunch of custom drawing going on making a normal QTextDocument somewhat impractical.

EDIT: I was incorrect, It seems that QTextDocument can render directly to a QPainter. Looks like what I need!

EDIT: It is unclear how to control where and how QTextDocument or QTextLayout will draw on a QPainter. I've attempted to use them to no avail. So if someone could provide a rudimentary example, that would be very helpful.

EDIT: I was eventually able to get what I wanted using something like this:

painter.setPen(default_color);
QTextDocument doc;
doc.setDefaultFont(font());
doc.setDocumentMargin(0);
doc.setPlainText(text);
highlighter_->setDocument(&doc);

painter.save();
painter.translate(x, y);
QAbstractTextDocumentLayout::PaintContext context;
context.palette.setColor(QPalette::Text, painter.pen().color());
doc.draw(&painter, context);
painter.restore();
like image 748
Evan Teran Avatar asked May 10 '26 15:05

Evan Teran


1 Answers

Qt provides a QSyntaxHighlighter that is probably exactly what you want. QSyntaxHighlighter uses a QTextDocument to mark each block of code with a specific state which can be associated with a specific presentation format.

The documentation on QSyntaxHighlighter provides a sample demonstrating how this may be accomplished and does some nice things:

  • Separates the model from presentation
  • Separates the formatting into different reusable classes (if implemented as such)
  • Supports the State design pattern if useful to your language
like image 165
Roger Lindsjö Avatar answered May 13 '26 04:05

Roger Lindsjö