Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QSyntaxHighlighter - text selection overrides style

Tags:

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?

like image 301
LogicStuff Avatar asked Jan 31 '15 22:01

LogicStuff


1 Answers

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)

like image 51
Bastien Thonnat Avatar answered Oct 05 '22 11:10

Bastien Thonnat