None:self.textEditor=ovid.textEditordefsetBoldT"/> None:self.textEditor=ovid.textEditordefsetBoldT">

Home  >  Article  >  Backend Development  >  Use PyQt6 to switch character formats

Use PyQt6 to switch character formats

PHPz
PHPzforward
2024-02-09 18:57:03680browse

使用 PyQt6 切换字符格式

Question content

I am writing a custom word processor as a hobby project. I'm using python and pyqt6.

I wrote the following. The purpose is that if I select some text and apply bold formatting (e.g. by hitting "ctrl-b") it will switch the formatting. Specifically, if all selected text is bold, the bold formatting should be removed. Otherwise, it will apply bold formatting.

class OvidFont:
    def __init__(self, ovid) -> None:
        self.textEditor = ovid.textEditor

    def setBoldText(self) -> None:
        fmt = QTextCharFormat()
        if self.textEditor.currentCharFormat().fontWeight() != QFont.Weight.Bold:
            print("    setting bold")   # for debugging
            fmt.setFontWeight(QFont.Weight.Bold)
        else:
            print("    setting normal") # for debugging
            fmt.setFontWeight(QFont.Weight.Normal)
        self.textEditor.textCursor().mergeCharFormat(fmt)

However, it does not remove bold formatting.

For example, in the sentence "this is a test", if I select "is a" and apply bold formatting, I get "this is a test" where "is a" is appropriate Bold. However, with the selection in place, if I hit "ctrl-b" it still remains bold. If I deselect the first or last character, the bold toggle works as expected. (I've tried inverting the if /else logic, but that also failed).

What did I miss?

Update: I added a working minimal test case at https://gist.github.com/ovid/65936985c6838c0220620cf40ba935fa


Correct answer


## The problem with the #setboldtext function is that it uses self.texteditor.currentcharformat().fontweight() to check the bold status, which only reflects the formatting of the character at the current cursor position, not the entire selected text format. If your cursor is at the beginning or end of the selection, it may not accurately represent the formatting of the entire selection.

So I use the existing cursor and adjust it as needed to check the formatting and apply the new font weight directly on

setfontweight().

Now it looks like this:

Updated code:

import sys
from PyQt6.QtWidgets import QTextEdit, QToolButton, QApplication, QMainWindow, QToolBar
from PyQt6.QtGui import QFont, QShortcut, QKeySequence, QTextCharFormat, QTextCursor

class OvidFont:
    def __init__(self, ovid) -> None:
        self.textEditor = ovid.textEditor

    def setBoldText(self):
        cursor = self.textEditor.textCursor()

        # If there's a selection, and the cursor is not at the block start and at the beginning of the selection,
        # move the cursor to the end of the selection
        if cursor.hasSelection() and not cursor.atBlockStart() and cursor.position() == cursor.selectionStart():
            cursor.setPosition(cursor.selectionEnd())

        # Check if the text (either selected or where the cursor is) is bold
        is_bold = cursor.charFormat().fontWeight() == QFont.Weight.Bold

        # Apply the new weight based on the current state
        new_weight = QFont.Weight.Normal if is_bold else QFont.Weight.Bold
        self.textEditor.setFontWeight(new_weight)

        print(f"Bold set to: {'Normal' if is_bold else 'Bold'}")

class Ovid(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("Ovid")
        self.setGeometry(100, 100, 200, 200)
        self.textEditor = QTextEdit()
        self.setCentralWidget(self.textEditor)
        self.fonts = OvidFont(self)

        self.toolbar = QToolBar("Main Toolbar")
        self.addToolBar(self.toolbar)

        bold_button = QToolButton()
        bold_button.setText("B")
        bold_button.setFont(QFont("Arial", 16, QFont.Weight.Bold))
        bold_button.setToolTip("Bold")
        bold_button.clicked.connect(self.fonts.setBoldText)
        self.toolbar.addWidget(bold_button)

        QShortcut(QKeySequence("Ctrl+B"), self, self.fonts.setBoldText)

def main():
    app = QApplication(sys.argv)
    ex = Ovid()
    ex.show()
    sys.exit(app.exec())

if __name__ == "__main__":
    main()

The above is the detailed content of Use PyQt6 to switch character formats. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete