Important: Please read the Qt Code of Conduct -

QLineEdit::setSelection and cursor in front, not at the end

  • Hi :-)

    I want to cache and restore the selection of a QLineEdit.

    When I use setSelection, the cursor is always put at the end of the selection. Is it possible to put it at the beginning (in case it was there before)? If I do a setCursorPosition (using the cached cursorPosition) after setting the selection, the cursor is at the right position, but the selection is gone. if I do it before, the cursor is put to the end of the selection by setSelection.

    Thanks for all help!

  • @l3u_

    the cursor is always put at the end of the selection. Is it possible to put it at the beginning (in case it was there before)?

    OOI, how would you get into that situation in the first place? The cursor is always at the end of the selection, e.g. if I drag-select left-to-right. The only way I can see you might have achieved this is if you previously dragged right-to-left? But in that situation I do not see any flashing caret/cursor at all, so I don't know where it is anyway?! Caret/cursor doesn't seem to much when there is a selection anyway, because if you type you won't be inserting you'll be overwriting....

  • You can simply hold shift and the left arrow key. The text is selected from right to left and the cursor is at the beginning of the selection.

  • Lifetime Qt Champion

    Did you try with negative length?
    void QLineEdit::setSelection(int start, int length)
    "Selects text from position start and for length characters. Negative lengths are allowed."

  • @mrjj I tried that, with the same result.

  • Lifetime Qt Champion

    the code just looked like it would set in other end in that case.

    void QWidgetLineControl::setSelection(int start, int length)
        if (Q_UNLIKELY(start < 0 || start > m_text.size())) {
            qWarning("QWidgetLineControl::setSelection: Invalid start position");
        if (length > 0) {
            if (start == m_selstart && start + length == m_selend && m_cursor == m_selend)
            m_selstart = start;
            m_selend = qMin(start + length, (int)m_text.length());
            m_cursor = m_selend;
        } else if (length < 0){
            if (start == m_selend && start + length == m_selstart && m_cursor == m_selstart)
            m_selstart = qMax(start + length, 0);
            m_selend = start;
            m_cursor = m_selstart;
        } else if (m_selstart != m_selend) {
            m_selstart = 0;
            m_selend = 0;
            m_cursor = start;
        } else {
            m_cursor = start;
        emit selectionChanged();

  • @mrjj That's the point: if length < 0, m_cursor is set to m_selstart, which is in this case the right border of the selection.

    Seems like it's simply not possible …

  • Lifetime Qt Champion

    ah, still reverse of what you want.
    Im not sure if possible, but if it loses selection moving the cursor it might be up hill.

  • @mrjj Well, after all, it's just a cosmetic thing. As soon as one presses a key, the selection is replaced by the first entered character anyway, no matter if the cursor is at the start or at the end of the selection.

  • Actually, QWidgetLineControl::setSelection does set the cursor to the beginning of the selection if a negative length is used. The reason I thought this was not possible is that I cached the output of selectionStart(), which is always the beginning of the selection, no matter how it was created, and selectedText().length().

    If one takes in account the position of the cursor and changes the values accordingly e. g. like this:

        if (m_editor->cursorPosition() == m_editor->selectionStart()) {
            m_selectionStart = m_editor->selectionStart() + m_editor->selectedText().length();
            m_selectionLength = m_editor->selectedText().length() * -1;
        } else {
            m_selectionStart = m_editor->selectionStart();
            m_selectionLength = m_editor->selectedText().length();

    and then calls setSelection, the cursor is set to the beginning if it was there before.

Log in to reply