Search code examples
cursorfocuspysideqlineeditinput-mask

PySide: reset cursor pos to 0 when clicking in QLineEdit in with input-mask


I'm trying to use a QLineEdit for input of six numbers with an input-mask, but the problem is that when the user clicks in the line-edit, the cursor position is exactly where you click.

I'm struggling to make sure it resets the position to the start. I've read similar questions - and answers to them - but I'm not able to get it working (a lot of them are in C++, and because I lack experience with it, I'm not able to replicate the code in Python).

I was able to install an event-filter that recognizes when the user clicks into the QLineEdit, and I'm able to print the cursor position that the user set when clicked. But when I try to manually set it to 0 it does not work. Well, it does work, but only if the whole application containing the QLineEdit loses focus and the user comes back to it. So in a way, I'm looking for a way to refresh/repaint the whole application inside the Filter class.

class Filter(QObject):
    def eventFilter(self, widget, event):
        # FocusIn event
        if event.type() == QEvent.FocusIn:
            print 'focus in'
            widget.setCursorPosition(0)
            return False

        else:
            return False

This sets the cursor position to 0, but in the actual application it shows only when I Alt+Tab or the whole window loses and gains focus again. Manual repaint()/update() of the widget/window does nothing.


Solution

  • I think the correct behaviour should be to always put the cursor at the beginning if the line-edit is empty. Otherwise, it should go wherever the user clicks, because they probably want to edit the specific character at that position.

    Here's a simple demo that implements that:

    import sys
    from PySide import QtCore, QtGui
    
    class Window(QtGui.QWidget):
        def __init__(self):
            super(Window, self).__init__()
            layout = QtGui.QVBoxLayout(self)
            while layout.count() < 2:
                edit = QtGui.QLineEdit(self)
                edit.setInputMask('999999')
                edit.installEventFilter(self)
                layout.addWidget(edit)
    
        def eventFilter(self, source, event):
            if event.type() == QtCore.QEvent.MouseButtonPress:
                if not len(source.text()):
                    source.home(False)
                    return True
            return super(Window, self).eventFilter(source, event)
    
    if __name__ == '__main__':
    
        app = QtGui.QApplication(sys.argv)
        window = Window()
        window.show()
        sys.exit(app.exec_())