How can I intercept when a widget loses its focus

后端 未结 1 1336
甜味超标
甜味超标 2021-01-12 17:01

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 virtu

1条回答
  •  日久生厌
    2021-01-12 17:15

    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:

    def my_handler(self, event):
        QtGui.QPlainTextEdit.focusOutEvent(self.my_text_edit, event)
        # my own handling follows...
    

    I don't understand why you can't use the focusChanged signal, though. The handler for it would simply be:

    def my_handler(self, old, new):
        if old is self.my_text_edit:
            print('focus out')
        elif new is self.my_text_edit:
            print('focus in')
    

    However, my own preference would be to use an event filter:

    class Window(QtGui.QMainWindow)
        def __init__(self):
            ...
            self.my_text_edit.installEventFilter(self)
    
        def eventFilter(self, source, event):
            if (event.type() == QtCore.QEvent.FocusOut and
                source is self.my_text_edit):
                print('eventFilter: focus out')
                # return true here to bypass default behaviour
            return super(Window, self).eventFilter(source, event)
    

    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.

    0 讨论(0)
提交回复
热议问题