pythonqtqlineedit

QLineEdit: blinking cursor (caret) disappears. How to restore it?


QLineEdit blinking cursor (caret) disappears when focusInEvent is overridden. How to restore the blinking cursor? Any idea?

from PySide6.QtWidgets import QApplication, QMainWindow, QLineEdit, QPushButton


class MyWindow(QMainWindow):

    def __init__(self):

        super().__init__()

        self.edt = QLineEdit(self)
        self.edt.move(10, 10)
        self.edt.focusInEvent = lambda event: self.on_focus_in_event(event)

        self.btn = QPushButton("OK", self)
        self.btn.move(10, 50)

    def on_focus_in_event(self, event):
        print("Doing something")
        self.edt.setFocus()


if __name__ == '__main__':
    app = QApplication()
    window = MyWindow()
    window.show()
    app.exec()

I tried some methods related to QLineEdit cursor but I couldn't solve the problem.


Solution

  • The way you redirect the event handling is wrong. This is not the way we are supposed to do it in Qt. At least not when you want to be able to call also the original event handler of QLineEdit which takes care if showing the caret. In other words, you have overwritten the original event handler (which shows the caret) and it is not called at all.

    If you want to do some action when the line edit gains focus, use event filters. This is exactly the perfect mechanism for your use case.

    from PySide6.QtCore import QEvent
    from PySide6.QtWidgets import QApplication, QMainWindow, QLineEdit, QPushButton
    
    
    class MyWindow(QMainWindow):
    
        def __init__(self):
            super().__init__()
    
            self.edt = QLineEdit(self)
            self.edt.move(10, 10)
            # installing event filter
            self.edt.installEventFilter(self)  
    
            self.btn = QPushButton("OK", self)
            self.btn.move(10, 50)
    
        def eventFilter(self, watched, event):
            # handling focus-in event of the QLineEdit
            if watched == self.edt and event.type() == QEvent.Type.FocusIn:
                print("Doing something")
                # returning False means that the original event handler is still called so that the caret gets visible
                return False
    
            # canonical way of handling of all other events
            return super().eventFilter(watched, event)
    
    
    if __name__ == '__main__':
        app = QApplication()
        window = MyWindow()
        window.show()
        app.exec()