Checking formatting of selected text in QTextEdit - PySide6
-
wrote on 2 Dec 2021, 19:45 last edited by tIk90wT 12 Mar 2021, 17:30
I' m working on a rich text editor and came across a small problem which I kind of solved with what seems like a "hack".
So I wanted to check if the selected text or the text in cursor position has any formatting, bold, italics etc and check the corresponding button that does the corresponding job but it gets weird.
if I do something like
if self.ed.fontItalic() is True: self.italic.setChecked(True) else: self.italic.setChecked(False) if self.ed.fontUnderline() is True: self.uline.setChecked(True) else: self.uline.setChecked(False)
where "self.italic" and "self.uline" are checkable QPushButtons;
Only the format under the cursor gets checked, but not both buttons for italic and underlined, ie, if the selected text has bot formatting.
Basically, it ignores the selected text and looks for formatting of text under cursor.
So I I'm currently parsing the html to see if it has formatting;
def check_formatting(self): if self.ed.textCursor().hasSelection(): print(self.ed.textCursor().selection().toHtml()) if "font-style:italic;" in self.ed.textCursor().selection().toHtml(): self.italic.setChecked(True) else: self.italic.setChecked(False) if "text-decoration: underline;" in self.ed.textCursor().selection().toHtml(): self.uline.setChecked(True) else: self.uline.setChecked(False) else: if self.ed.fontItalic() is True: self.italic.setChecked(True) else: self.italic.setChecked(False) if self.ed.fontUnderline() is True: self.uline.setChecked(True) else: self.uline.setChecked(False)
and code for formatting selected text or text under cursor on button click is as follows
def set_italic(self): if self.italic.isChecked(): self.ed.setFontItalic(True) if self.ed.textCursor().hasSelection(): if self.ed.fontItalic() != QTextFormat.FontItalic: self.ed.setFontItalic(True) else: self.ed.setFontItalic(False) else: self.ed.setFontItalic(False)
All of this works nearly as intended but it all feels super hacky. And with the html parsing, obviously, if the user enters "font-style:italic;" in the text edit and selects the entered text, button for italic gets checked.
I've been looking through a lot of stuff on the internet but none of them helps me achieve as much as the above code does.
-
Hi,
@tIk90wT said in Checking formatting of selected text in QTextEdit - PySide6:
if self.ed.fontItalic() is True:
self.italic.setChecked(True)
else:
self.italic.setChecked(False)That can be simplified:
self.italic.setChecked(self.ed.fontItalic())
Just to be sure I understand correctly, if you have your cursor on a bit of text that has both italic and underline, only italic is true ?
-
Hi,
@tIk90wT said in Checking formatting of selected text in QTextEdit - PySide6:
if self.ed.fontItalic() is True:
self.italic.setChecked(True)
else:
self.italic.setChecked(False)That can be simplified:
self.italic.setChecked(self.ed.fontItalic())
Just to be sure I understand correctly, if you have your cursor on a bit of text that has both italic and underline, only italic is true ?
wrote on 2 Dec 2021, 20:24 last edited by tIk90wT 12 Feb 2021, 20:36@SGaist If I use
if self.ed.fontItalic() is True: self.italic.setChecked(True) else: self.italic.setChecked(False) if self.ed.fontUnderline() is True: self.uline.setChecked(True) else: self.uline.setChecked(False)
and select a bunch of text that has italics, and bold it ignores what's in the selection and gets the format right from the cursor position.
Like, if text at cursor position has italic only, it checks italic, or has italics and underline, it checks both. If the selection has both italic, underline etc but the text at cursor position has no format, nothing gets checked.
-
Ok, i understand better. In your case you should go through all the blocks included in your selection and then adjust the buttons based on the format of these blocks.
-
Ok, i understand better. In your case you should go through all the blocks included in your selection and then adjust the buttons based on the format of these blocks.
-
Yes, you would need to go from the start to the end of the selection and get the format of everything in between.
-
Yes, you would need to go from the start to the end of the selection and get the format of everything in between.
-
I was thinking about selectionStart and selectionEnd.
-
I was thinking about selectionStart and selectionEnd.
wrote on 3 Dec 2021, 20:54 last edited by tIk90wT 12 Mar 2021, 20:57@SGaist I came up with the following and it works but I'm not sure if it's exactly what you were talking about...
self.editor.cursorPositionChanged.connect(self.check_formatting) def check_formatting(self): if self.ed.textCursor().hasSelection(): cur = self.ed.textCursor() cur.setPosition(self.ed.textCursor().selectionStart()) cur.setPosition(self.ed.textCursor().selectionEnd(), QTextCursor.KeepAnchor) ss = cur.selectionStart() se = cur.selectionEnd() while ss < se: cur.setPosition(ss) if cur.charFormat().fontItalic(): self.italic.setChecked(True) if cur.charFormat().fontUnderline(): self.uline.setChecked(True) if cur.charFormat().fontWeight() == QFont.Bold: self.bold.setChecked(True) if cur.charFormat().background().style() != Qt.BrushStyle.NoBrush: self.higl.setChecked(True) ss += 1 else: cur = self.ed.textCursor() self.italic.setChecked(cur.charFormat().fontItalic()) self.uline.setChecked(cur.charFormat().fontUnderline()) if cur.charFormat().fontWeight() == QFont.Bold: self.bold.setChecked(True) else: self.bold.setChecked(False) if cur.charFormat().background().style() != Qt.BrushStyle.NoBrush: self.higl.setChecked(True) else: self.higl.setChecked(False)
PS: Big thanks for helping me reach this point. I'm a complete noob when it come to all the text processing stuffs.
-
@SGaist I came up with the following and it works but I'm not sure if it's exactly what you were talking about...
self.editor.cursorPositionChanged.connect(self.check_formatting) def check_formatting(self): if self.ed.textCursor().hasSelection(): cur = self.ed.textCursor() cur.setPosition(self.ed.textCursor().selectionStart()) cur.setPosition(self.ed.textCursor().selectionEnd(), QTextCursor.KeepAnchor) ss = cur.selectionStart() se = cur.selectionEnd() while ss < se: cur.setPosition(ss) if cur.charFormat().fontItalic(): self.italic.setChecked(True) if cur.charFormat().fontUnderline(): self.uline.setChecked(True) if cur.charFormat().fontWeight() == QFont.Bold: self.bold.setChecked(True) if cur.charFormat().background().style() != Qt.BrushStyle.NoBrush: self.higl.setChecked(True) ss += 1 else: cur = self.ed.textCursor() self.italic.setChecked(cur.charFormat().fontItalic()) self.uline.setChecked(cur.charFormat().fontUnderline()) if cur.charFormat().fontWeight() == QFont.Bold: self.bold.setChecked(True) else: self.bold.setChecked(False) if cur.charFormat().background().style() != Qt.BrushStyle.NoBrush: self.higl.setChecked(True) else: self.higl.setChecked(False)
PS: Big thanks for helping me reach this point. I'm a complete noob when it come to all the text processing stuffs.
@tIk90wT said in Checking formatting of selected text in QTextEdit - PySide6:
cur.setPosition(self.ed.textCursor().selectionStart())
cur.setPosition(self.ed.textCursor().selectionEnd(), QTextCursor.KeepAnchor)I don't think you need that since the selection is already there.
-
@tIk90wT said in Checking formatting of selected text in QTextEdit - PySide6:
cur.setPosition(self.ed.textCursor().selectionStart())
cur.setPosition(self.ed.textCursor().selectionEnd(), QTextCursor.KeepAnchor)I don't think you need that since the selection is already there.
1/11