Skip to content

Instantly share code, notes, and snippets.

@tritium21
Forked from ssokolow/spelltextedit.py
Created September 18, 2019 08:46
Show Gist options
  • Save tritium21/f09ce417edd035fca488fd2b1f7ec2a8 to your computer and use it in GitHub Desktop.
Save tritium21/f09ce417edd035fca488fd2b1f7ec2a8 to your computer and use it in GitHub Desktop.
Spell-checked QPlainTextEdit for PyQt 5.x using PyEnchant
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""QPlainTextEdit With In Line Spell Check
Source:
https://nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/
"""
__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 QMenu
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()
self.highlighter = Highlighter(self.document())
self.highlighter.setDict(self.dict)
def contextMenuEvent(self, event):
popup_menu = self.createStandardContextMenu()
# Select the word under the cursor.
cursor = self.cursorForPosition(event.pos())
cursor.select(QTextCursor.WordUnderCursor)
self.setTextCursor(cursor)
# Check if the selected word is misspelled and offer spelling
# suggestions if it is.
if cursor.hasSelection():
text = unicode(cursor.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())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment