PHP前端开发

使用 PyQt6 切换字符格式

百变鹏仔 1天前 #Python
文章标签 字符
问题内容

我正在编写一个自定义文字处理器作为一个业余爱好项目。我正在使用 python 和 pyqt6。

我写了以下内容。目的是,如果我选择一些文本并应用粗体格式(例如,通过点击“ctrl-b”),它将切换格式。具体来说,如果所有选定的文本都是粗体,则应删除粗体格式。否则,它将应用粗体格式。

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)

但是,它不会删除粗体格式。

例如,在句子“this is a test”中,如果我选择“is a”并应用粗体格式,我会得到“this is a test”,其中“is a” “适当大胆。然而,选择到位后,如果我点击“ctrl-b”,它仍然保持粗体。如果我取消选择第一个或最后一个字符,粗体切换将按预期工作。 (我尝试过反转 if/else 逻辑,但也失败了)。

我错过了什么?

更新:我在 https://gist.github.com/ovid/65936985c6838c0220620cf40ba935fa 添加了一个有效的最小测试用例


正确答案


setboldtext 函数的问题在于它使用 self.texteditor.currentcharformat().fontweight() 检查粗体状态,这仅反映当前光标位置处字符的格式,而不是整个选定文本的格式。如果您的光标位于所选内容的开头或结尾,它可能无法准确表示整个所选范围的格式。

因此,我使用现有的光标,并根据需要进行调整以检查格式,并在 setfontweight() 上直接应用新的字体粗细。

现在看起来像这样:

更新的代码:

import sysfrom PyQt6.QtWidgets import QTextEdit, QToolButton, QApplication, QMainWindow, QToolBarfrom PyQt6.QtGui import QFont, QShortcut, QKeySequence, QTextCharFormat, QTextCursorclass 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()