QSyntaxHighlighter - text selection overrides style
Asked Answered
B

1

23

I'm making a custom code editor with QPlainTextEdit and QSyntaxHighlighter and I've encountered a glitch. I'd like to preserve syntax highlighting even within a selection. However, colors of the selection (environment colors) override the colors of the text highlighted by QSyntaxHighlighter and html tags. Other attributes like font family are preserved.


Example:

No selection:             Selection:
Unselected      Selected
                                   (I'd like Hello to be green and World! to be black)


I've also tried to set the style sheet to:

QPlainTextEdit {
    selection-color: rgba(0, 0, 0, 0);
    selection-background-color: lightblue;
}

Result:

enter image description here
Background color overlays the text and well, text color with alpha = 0 is not visible. I've done that just to rule out the idea that syntax color persists under selection-color. It is in fact overlaid by selection-background-color.
Edit: No, if I also set selection-background-color to rgba(0, 0, 0, 0), there's no selection and there's no text in that selection. All I see is the background.


Approach of the following snippet which makes whole cursor's line highlighted seems like the way to go, but I would basically end up reimplementing all the selection mechanics...

QList<QTextEdit::ExtraSelection> extraSelections;
QTextCursor cursor = textCursor();

QTextEdit::ExtraSelection selection;
selection.format.setBackground(lineHighlightColor_);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = cursor;
selection.cursor.clearSelection();
extraSelections.append(selection);
setExtraSelections(extraSelections);

Is there any simpler solution to this?

Bream answered 31/1, 2015 at 22:3 Comment(3)
did you ever find a simpler solution?Hypsography
@NicolasHolthaus I've resigned. If I had found a simpler approach (I don't know if QTextEdit::ExtraSelection is a viable solution), I would have shared it.Bream
this is a really annoying limitation of the syntax highlighter.Hypsography
C
5

the problem reside here :

https://github.com/qt/qtbase/blob/e03b64c5b1eeebfbbb94d67eb9a9c1d35eaba0bb/src/widgets/widgets/qplaintextedit.cpp#L1939-L1945

QPlainTextEdit use context palette instead of current selection format.

You could create one class inheritings from QPlainTextEdit and override paintEvent

signature :

void paintEvent(QPaintEvent *);

Copy the body of the function from github inside the new class paintEvent function :

https://github.com/qt/qtbase/blob/e03b64c5b1eeebfbbb94d67eb9a9c1d35eaba0bb/src/widgets/widgets/qplaintextedit.cpp#L1883-L2013

add this function in your cpp file before paintEvent (PlainTextEdit paintEvent need it) :

https://github.com/qt/qtbase/blob/e03b64c5b1eeebfbbb94d67eb9a9c1d35eaba0bb/src/widgets/widgets/qplaintextedit.cpp#L1861-L1876

add

#include <QPainter>
#include <QTextBlock>
#include <QScrollBar>

and replace each occurrence of

o.format = range.format;

whith

o.format = range.cursor.blockCharFormat();
o.format.setBackground(QColor(your selection color with alpha));

with that your custom PlainTextEdit check the format linked to the current char instead of your PlainTextEdit palette

(beware (L)GPL licence, I just give an opensource workaround)

Connoisseur answered 11/10, 2017 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.