I have a QPlainTextEdit and want to process the content when it loses focus. I've seen that I can either do this with the focusChanged event or with the focusOutEvent virtual function.
I don't know how to pass parameters with the new syntax (i.e. my_app.focusChanged.connect(my_handler)
where my_handler
is a locally defined function). So I tried working with the virtual function.
Since the interface is created with QT Designer inheriting QPlainTextEdit
would be an overkill, so I tried to override the virtual function by simply using my_text_edit.focusOutEvent = my_handler
. This did intercept the message as I wanted, but it apparently overwrote some built in functionality in QPlainTextEdit
and I get artefacts - namely the cursor from the text edit does not disappear when it looses focus. I figured that I should somehow call the original event and what worked for me was the following:
In my __init__
method I have:
self.original_handler = self.my_text_edit.focusOutEvent
self.my_text_edit.focusOutEvent = self.my_handler
The definition of my_handler
is:
def my_handler(self, event):
self.original_handler(event)
# my own handling follows...
I am basically replicating what I expect the library to do for me. I find this too clumsy and I can see how it can backfire in many ways during maintenance. Can anyone suggest a neater way to do it? Thanks!
Personally, I never use the monkey-patching style of overriding virtual methods, but the correct way to retain the original behaviour would be to call the base-class method directly, like this:
I don't understand why you can't use the
focusChanged
signal, though. The handler for it would simply be:However, my own preference would be to use an event filter:
This is a much more flexible solution, which provides a generic way to handle any event type for any widget that has been imported via Qt Designer (or, in fact, any widget that you just don't want to subclass).
There is also the possibility of widget promotion, which can be used to directly replace the widgets in generated ui modules with your own subclasses. This would then allow you to override any virtual methods via inheritance, rather than monkey-patching individual instances. If you are importing several widgets of the same type from Qt Designer which share a lot of custom functionality, this can provide a very clean solution.
A simple explanation of how to do widget promotion in PyQt can be found in my answer to: Replace QWidget objects at runtime.