TL;DR: Code here
UPDATE: A “fake
QLineEdit” version for adding spell-checking to most places where you’d use
QLineEdit is now available.
One of the projects I’ve been working on recently is a proper replacement for the hacky way I handle desktop notes and “scratch paper”. (Abusing Leafpad windows as pseudo-sticky notes so I have things which are proper windows which show up in the taskbar because I almost never see my desktop.)
Well, one thing that I’ve always wanted was as-you-type spell checking in my stickies and scratch spaces, so I got to Googling and found this bit of code for PyQt4 by John Schember.
I liked where it was going, but realized I could do much better. (eg. It shouldn’t be meddling with the visible cursor and selection to do background processing.)
The changes I made as of this post are as follows:
- Brought the declaration of MIT license terms up to my standards.
- Reformatted it to satisfy PEP8 and match my preferred code style.
- Ported it to Python 3.x and PyQt5
- Refactored the code to be cleaner (Both the fix from Jonas F. Jensen’s comment on the original and many fixes of my own.)
- Reworked things so the user’s cursor and selection are left un-touched. (Qt supports having additional ones which aren’t shown to the user.)
- Switched to using PyEnchant’s tokenizer for both highlighting and generation of spelling suggestions to minimize false positives.
- Reworked the API to better support dropping this code into a larger application, unmodified, rather than using it as a starting-point to be copy-pasted.
- Added context submenus to allow changing the spelling language or ignoring HTML tags.
- Enabled the PyEnchant tokenizer’s URL filter to avoid false positives.
- Added a workaround for a cursor-focus bug I observed in Qt 5.2.1.
It’s not yet perfect, but I think this is as far as I’ll go with the MIT-licensed version. (eg. I’m using a version of PyEnchant which doesn’t yet include an implementation of levenshtein distance, I don’t feel like writing one from scratch, and none of the ready-made ones I could embed have MIT-compatible licenses.)