PyQt - 如何开启/关闭拼写检查

4 投票
1 回答
1563 浏览
提问于 2025-04-17 09:30

我正在用以下内容作为我编辑器拼写检查器的基础。我想做一个自动拼写检查按钮,按下时拼写检查器会工作,而不按时拼写检查器就不应该高亮或建议任何内容。你知道的,类似于LibreOffice/OpenOffice的自动拼写检查工具栏按钮?

我可以让这个按钮正常工作,没问题。我的问题是该如何处理高亮显示的部分?如果在按下按钮时创建高亮显示类,那么在按钮没有按下时我该怎么做呢?直接删除高亮显示类并不奏效。

我找到了如何关闭右键菜单的方法:

if self.actionSpellCheck.isChecked(): #This is my auto-spellchecking button
    popup_menu.exec_(event.globalPos())

好的,我明白了,要关闭高亮显示,我只需要把高亮显示的字典设置为None:

self.highlighter.setDict(None)

要重新开启高亮显示,只需把字典重新设置为高亮显示的内容:

self.highlighter.setDict(self.dict)

谢谢。

下面是我添加了工具栏和按钮的原始代码:

__license__ = 'MIT'
__copyright__ = '2009, John Schember '
__docformat__ = 'restructuredtext en'

import re
import sys

import enchant

from PyQt4.Qt import QAction
from PyQt4.Qt import QApplication
from PyQt4.Qt import QEvent
from PyQt4.Qt import QMenu
from PyQt4.Qt import QMouseEvent
from PyQt4.Qt import QPlainTextEdit
from PyQt4.Qt import QSyntaxHighlighter
from PyQt4.Qt import QTextCharFormat
from PyQt4.Qt import QTextCursor
from PyQt4.Qt import Qt
from PyQt4.QtCore import pyqtSignal

class SpellTextEdit(QPlainTextEdit):

    def __init__(self, *args):
        QPlainTextEdit.__init__(self, *args)

        # Default dictionary based on the current locale.
        self.dict = enchant.Dict("ru_RU")
        self.highlighter = Highlighter(self.document())
        self.highlighter.setDict(self.dict)

    def mousePressEvent(self, event):
        if event.button() == Qt.RightButton:
            # Rewrite the mouse event to a left button event so the cursor is
            # moved to the location of the pointer.
            event = QMouseEvent(QEvent.MouseButtonPress, event.pos(),
                Qt.LeftButton, Qt.LeftButton, Qt.NoModifier)
        QPlainTextEdit.mousePressEvent(self, event)

    def contextMenuEvent(self, event):
        popup_menu = self.createStandardContextMenu()

        # Select the word under the cursor.
        cursor = self.textCursor()
        cursor.select(QTextCursor.WordUnderCursor)
        self.setTextCursor(cursor)

        # Check if the selected word is misspelled and offer spelling
        # suggestions if it is.
        if self.textCursor().hasSelection():
            text = unicode(self.textCursor().selectedText())
            if not self.dict.check(text):
                spell_menu = QMenu('Spelling Suggestions')
                for word in self.dict.suggest(text):
                    action = SpellAction(word, spell_menu)
                    action.correct.connect(self.correctWord)
                    spell_menu.addAction(action)
                # Only add the spelling suggests to the menu if there are
                # suggestions.
                if len(spell_menu.actions()) != 0:
                    popup_menu.insertSeparator(popup_menu.actions()[0])
                    popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)

        popup_menu.exec_(event.globalPos())

    def correctWord(self, word):
        '''
        Replaces the selected text with word.
        '''
        cursor = self.textCursor()
        cursor.beginEditBlock()

        cursor.removeSelectedText()
        cursor.insertText(word)

        cursor.endEditBlock()


class Highlighter(QSyntaxHighlighter):

    WORDS = u'(?iu)[\w\']+'

    def __init__(self, *args):
        QSyntaxHighlighter.__init__(self, *args)

        self.dict = None

    def setDict(self, dict):
        self.dict = dict

    def highlightBlock(self, text):
        if not self.dict:
            return

        text = unicode(text)

        format = QTextCharFormat()
        format.setUnderlineColor(Qt.red)
        format.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)

        for word_object in re.finditer(self.WORDS, text):
            if not self.dict.check(word_object.group()):
                self.setFormat(word_object.start(),
                    word_object.end() - word_object.start(), format)


class SpellAction(QAction):

    '''
    A special QAction that returns the text in a signal.
    '''

    correct = pyqtSignal(unicode)

    def __init__(self, *args):
        QAction.__init__(self, *args)

        self.triggered.connect(lambda x: self.correct.emit(
            unicode(self.text())))


def main(args=sys.argv):
    app = QApplication(args)

    spellEdit = SpellTextEdit()
    spellEdit.show()

    return app.exec_()

if __name__ == '__main__':
    sys.exit(main())

1 个回答

3

你可以通过使用它的 setDocument 方法来开启或关闭语法高亮功能。

SpellTextEdit 类会保存它的高亮器的引用,所以只需要像下面这样添加几个方法:

def highlighterEnabled(self):
     return self.highlighter.document() is not None

def setHighlighterEnabled(self, enable):
    if enable != self.highlighterEnabled():
        if enable:
            self.highlighter.setDocument(self.document())
        else:
            self.highlighter.setDocument(None)

撰写回答