Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved How to change color only in selected letters in QLineEdit?

    General and Desktop
    6
    15
    3810
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      TomNow99 last edited by

      Hello,

      I have QLineEdit and a text on it ( for example "abcdef" ). I select by mouse a part of the text "cdef".
      Now I would like to change color of that part of the text "cdef" to green. So I would like to have in this QLineEdit text letters:
      a // in black
      b // in black
      c // in green
      d // in green
      e // in green
      f // in green

      I try with setStyleSheet() but when I select text and use:

          line->setStyleSheet("QLineEdit {color: green}");
      

      I get the whole green text in this QLineEdit.

      I tried with setStyleSheet and selection-color, but this in not what I want.

      I prefer to use setStyleSheet.

      Here is the image what I would like to:

      exe.png

      JonB eyllanesc B 3 Replies Last reply Reply Quote 0
      • JonB
        JonB @TomNow99 last edited by

        @TomNow99
        QLineEdit accepts HTML/rich text. You will need to use that within the text to achieve certain characters in one color and others in another.

        1 Reply Last reply Reply Quote 1
        • T
          TomNow99 last edited by TomNow99

          @JonB But this is possible in QLineEdit?

          EDIT:

          I have to use setStyleSheet?

          JonB 1 Reply Last reply Reply Quote 0
          • JonB
            JonB @TomNow99 last edited by JonB

            @TomNow99
            No, you won't be able to use stylesheet because that won't be able to address individual letters. You will have to use (in-line, as the actual content in the line edit) something like one of:

            ab<span style="color: green;">cdef</span>
            ab<font color="green">cdef</font>
            

            depending on what QLineEdit accepts.

            BTW, officially QLineEdit apparently does not support rich text, you're supposed to use QTextEdit for that. But in practice it does accept rich text, at least to some extent. If you get stuck try QTextEdit if you think what you're trying ought to be working.

            1 Reply Last reply Reply Quote 3
            • eyllanesc
              eyllanesc @TomNow99 last edited by eyllanesc

              @TomNow99 You have to use QPalette:

              QPalette pal = line->palette();
              pal.setColor(QPalette::HighlightedText, QColor("green"));
              pal.setColor(QPalette::Highlight, QColor("transparent"));
              line->setPalette(pal);
              

              Screenshot

              If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

              HeerokNewbie 1 Reply Last reply Reply Quote 4
              • B
                Bonnie @TomNow99 last edited by

                @TomNow99 said in How to change color only in selected letters in QLineEdit?:

                I tried with setStyleSheet and selection-color, but this in not what I want.

                What did you try and what do you want exactly?

                @eyllanesc said in How to change color only in selected letters in QLineEdit?:

                You have to use QPalette:

                Your palette code can also be replaced by style sheet:

                selection-color: green; selection-background-color: transparent;
                

                So I'm not sure this is what the OP wants.

                JonB 1 Reply Last reply Reply Quote 0
                • T
                  TomNow99 last edited by TomNow99

                  @eyllanesc @Bonnie I need something other

                  I would like to do something like in MS Word.

                  I write a text in MS Word document - "abcdef"

                  Next I would like to change a color in a part of this text - "cde"

                  What I do in MS Word?

                  I select part "cde" by mouse and click button "change font color" and choose red color.

                  Now I have 3 parts:
                  "ab" which is black
                  "cde" which is red
                  "f" which is black

                  I would like to do the same in QT in QLineEdit. I find that QTextEdit have what I would like:

                  edit->setTextColor(Qt::red);
                  

                  But this is QTextEdit - I would like the same effect in QLineEdit.

                  B 1 Reply Last reply Reply Quote 0
                  • JonB
                    JonB @Bonnie last edited by JonB

                    @Bonnie said in How to change color only in selected letters in QLineEdit?:

                    selection-color: green;

                    I had not noticed the OP's question as saying anything about what he wants in green being selected, but now I see

                    I select by mouse a part of the text "cdef".

                    @TomNow99
                    Do you want the green only while the text remains selected, or did you want it stay green after having selected and no longer selected?
                    EDIT Even after your latest clarification this remains unclear --- need a clear answer to this question?

                    1 Reply Last reply Reply Quote 0
                    • T
                      TomNow99 last edited by

                      @JonB I would like to stay that new color ( green / red ) after unselected.

                      JonB 1 Reply Last reply Reply Quote 0
                      • B
                        Bonnie @TomNow99 last edited by Bonnie

                        @TomNow99
                        In that case it is rich text.
                        As @JonB said you need to set HTML codes.
                        Stylesheet cannot do that.

                        But I'm not sure if QLineEdit supports rich text?
                        I don't see that in the doc, only

                        A related class is QTextEdit which allows multi-line, rich text editing.

                        So maybe you need to use QTextEdit.

                        1 Reply Last reply Reply Quote 0
                        • JonB
                          JonB @TomNow99 last edited by JonB

                          @TomNow99
                          Yes, that's what I suspected! So a stylesheet changing the color while selected will not do the job.

                          I find that QTextEdit have what I would like:
                          edit->setTextColor(Qt::red);

                          That should set the whole of the text edit red?

                          As I said earlier, I do believe that do color on some of the content but not all characters will require you to insert HTML/rich-text like I showed you earlier. Did you try that on a QLineEdit, I believe it's supposed to work on that as well as on a QTextEdit though it may not be documented, as per the reference I gave you before? Otherwise, if you can't get that to work on a QLineEdit you really need to change over top a QTextEdit for just this purpose?

                          1 Reply Last reply Reply Quote 1
                          • T
                            TomNow99 last edited by TomNow99

                            @JonB

                            a1.png

                            a2.png

                            a3.png

                            a4.png

                            Of course I can use QTextEdit, but here is other problem: I would like to have only one line.

                            I would like to avoid HTML, but of course this is solution :)

                            EDIT:

                            In this situation ( pictures ): now when I add new text it should be green

                            JonB 1 Reply Last reply Reply Quote 0
                            • JonB
                              JonB @TomNow99 last edited by JonB

                              @TomNow99

                              Of course I can use QTextEdit, but here is other problem: I would like to have only one line.

                              It's not good, but you might look at e.g. https://stackoverflow.com/a/45310325/489865

                              I would like to avoid HTML, but of course this is solution :)

                              Well, you can't, at least not easily. How do you intended to get color into plain text?

                              I have now suggested/asked you twice whether you find the HTML/rich-text does work inside a QLineEdit as well as in a QTextEdit, e.g. according to @raven-worx https://forum.qt.io/topic/69878/qcombobox-how-to-get-richtext-in-qlineedit/2

                              Have you tried it yet?

                              1 Reply Last reply Reply Quote 0
                              • H
                                hayden48 last edited by hayden48

                                I was able to accomplish this by overlaying a QLabel on top of a QLineEdit then making the text color of the line edit white. When the textEdited signal is emitted, use it to update the text of the QLabel. The QLabel accepts rich text so you can process the text in the QLineEdit and replace key words with the HTML needed to display the text in the way you want it. I'm sure you could modify the code to change the text color of the current selection.

                                class LabelEditPair(QLineEdit):
                                    """
                                    QLineEdit that changes the color of the word 'blue' to blue and
                                    the changes the font weight of the word 'bold' to bold.
                                    """
                                    def __init__(self):
                                        super().__init__()
                                
                                        self.label = QLabel("starting out")
                                        self.label.setParent(self)
                                        self.label.move(3, 0)
                                        self.label.setAttribute(Qt.WA_TransparentForMouseEvents)
                                        self.setStyleSheet("QLineEdit{color: white}")
                                
                                        self.textEdited.connect(self.text_edited)
                                
                                    def resizeEvent(self, event):
                                        self.label.setFixedHeight(self.height())
                                        self.label.setFixedWidth(self.width())
                                        super().resizeEvent(event)
                                
                                    def text_edited(self, text):
                                        text = text.replace("blue", "<span style='color: blue'>blue</span>")
                                        text = text.replace("bold", "<span style='font-weight: bold'>bold</span>")
                                        self.label.setText(text)
                                

                                27371297-5372-48fa-8d88-826b69cf6eef-image.png

                                EDIT

                                The previous example doesn't work well in instances where the text overflows from the QLineEdit widget. Here is a more comprehensive widget that uses the same idea but instead of making a subclass of QLineEdit the widget is a subclass of QFrame with a QLineEdit and two QLabels, one before the cursor and one after. The widget replaces regex matches with HTML to change the style of those characters.

                                class LabelEditPair(QFrame):
                                    """
                                    QLineEdit that changes the color of the word 'blue' to blue and
                                    the changes the font weight of the word 'bold' to bold.
                                    """
                                    def __init__(self, initial_text: str):
                                        super().__init__()
                                
                                        self.stylized_regex: List[Tuple[str, str]] = []
                                
                                        self.setFixedHeight(22)
                                        self.setObjectName("frame")
                                        self.setStyleSheet("QFrame#frame{background-color: white; border: 1px solid gray}"
                                                           "QFrame:hover#frame{border: 1px solid black}"
                                                           "QFrame:selected#frame{border: 1px solid blue}")
                                        self.setFrameStyle(QFrame.Box)
                                        self.line_edit = QLineEdit(initial_text)
                                        self.line_edit.setParent(self)
                                        self.line_edit.move(0, 2)
                                        self.line_edit.setStyleSheet("border: 0px solid white; background-color:transparent")
                                
                                        self.line_edit.setFixedWidth(2**16)
                                
                                        self.left_label = QLabel()
                                        self.left_label.setParent(self.line_edit)
                                        self.left_label.move(1, 1)
                                        self.left_label.setAlignment(Qt.AlignRight)
                                        self.left_label.setAttribute(Qt.WA_TransparentForMouseEvents)
                                
                                        self.right_label = QLabel()
                                        self.right_label. setParent(self.line_edit)
                                        self.right_label.move(5, 1)
                                        self.right_label.setAlignment(Qt.AlignLeft)
                                        self.right_label.setAttribute(Qt.WA_TransparentForMouseEvents)
                                        self.right_label.setFixedWidth(2**16)
                                        self.offset = 0
                                
                                        self.line_edit.textEdited.connect(self.text_edited)
                                        self.line_edit.cursorPositionChanged.connect(self.apply_shift)
                                        self.line_edit.selectionChanged.connect(self.set_text_to_update)
                                        self.update_text_needed = True
                                
                                        self.placeholder = ""
                                        self.color = (0, 0, 0)
                                
                                    def text(self):
                                        return self.line_edit.text()
                                
                                    def setReadOnly(self, read_only: bool):
                                        self.line_edit.setReadOnly(read_only)
                                        self.line_edit.setAttribute(Qt.WA_TransparentForMouseEvents, read_only)
                                        self.line_edit.end(False)
                                
                                    def set_placeholder_text(self, text: str):
                                        self.placeholder = text
                                
                                    def set_text_color(self, color: Tuple[int, int, int]):
                                        self.color = color
                                
                                    def set_text_to_update(self):
                                        self.update_text_needed = True
                                
                                    def text_edited(self, text: str):
                                        if len(text) == 0:
                                            self.left_label.setText(self.placeholder)
                                            self.left_label.setStyleSheet("color: gray")
                                            return
                                        self.left_label.setStyleSheet(f"color: rbg{self.color}")
                                        new = self.line_edit.cursorPosition()
                                        left_text = text[:new]
                                        right_text = text[new:]
                                        self.left_label.setText(left_text)
                                        self.right_label.setText(right_text)
                                        for style, regex in self.stylized_regex:
                                            matches = findall(regex, left_text)
                                            for match in matches:
                                                left_text = left_text.replace(match, f"<span style='{style}'>{match}</span>")
                                                self.left_label.setText(left_text)
                                            matches_right = findall(regex, right_text)
                                            for match in matches_right:
                                                right_text = right_text.replace(match, f"<span style='{style}'>{match}</span>")
                                                self.right_label.setText(right_text)
                                        self.update_text_needed = False
                                
                                    def add_style_for_regex(self, style: str, regex: str):
                                        self.stylized_regex.append((style, regex))
                                
                                    def apply_shift(self, old=None, new=None):
                                        text = self.line_edit.text()
                                        rect = self.line_edit.cursorRect()
                                        x_pos = rect.x()
                                        if x_pos + self.offset > self.width() - 8 and new == old + 1:
                                            self.offset = -1*(x_pos - (self.width()-8))
                                        elif new + 1 == old and x_pos + self.offset < self.width() * 1/2:
                                            self.offset += 5
                                        self.offset = min(0, self.offset)
                                        if len(text) == 0:
                                            self.offset = 0
                                        self.line_edit.move(self.offset, 2)
                                        self.left_label.setFixedWidth(x_pos + 4)
                                        self.right_label.move(x_pos + 5, 1)
                                        if self.update_text_needed:
                                            self.text_edited(text=text)
                                        self.update_text_needed = True
                                

                                example usage

                                self.color_edit = LabelEditPair("")
                                self.color_edit.add_style_for_regex("color: blue", "(?:HI|HELLO)")
                                main_layout.addWidget(self.color_edit)
                                

                                e0e6676f-4dd8-4057-ba0c-87ae009bd680-image.png

                                1 Reply Last reply Reply Quote 0
                                • HeerokNewbie
                                  HeerokNewbie @eyllanesc last edited by

                                  @eyllanesc Your answer is helpful for me. Thanks

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post