2

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();
Evan Teran
  • 87,561
  • 32
  • 179
  • 238

2 Answers2

5

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
feedc0de
  • 3,646
  • 8
  • 30
  • 55
Kaleb Pederson
  • 45,767
  • 19
  • 102
  • 147
  • Also, why did you community wiki your answer? You won't get the rep points for your answer... – Evan Teran May 27 '09 at 19:34
  • Woah, I just noticed QTextDocument has a drawContents which draws to a QPainter. Now *that* is helpful! I think we may have a winner. – Evan Teran May 27 '09 at 19:40
  • Re: community wiki... because I'm still a noob and am trying to figure out how SO works :(. Thanks for the heads up! – Kaleb Pederson May 27 '09 at 22:47
0

I'd use either QTextEdit or directlay its underlining engine QTextDocument.

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267