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:
(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:
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?
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With