Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I move the keyboard cursor/focus to a QLineEdit?

Tags:

qt

I am opening a QDialog which contains a QLineEdit. I want the QLineEdit to have keyboard focus initially, with the blinking cursor as a visual cue. Simple, right?

Calling line_edit->setFocus() has no effect.

Calling line_edit->grabKeyboard() gives it input focus BUT

  • the blinking caret doesn't move to line_edit
  • if I click into a different QLineEdit, the blinking caret goes there but keypresses are still delivered to line_edit

If I do neither, I have to click into line_edit to get the caret and input focus. Looking at the source code for QLineEdit::mousePressEvent it seems that the critical function is QWidgetLineControl::moveCursor, but that's not accessible via the public API and peeking further into the source doesn't show anything promising.

So how do I move the damn keyboard input cursor?

like image 354
spraff Avatar asked Mar 03 '16 03:03

spraff


Video Answer


2 Answers

How do I set the keyboard input cursor to QLineEdit widget?

From one of replies to this thread: Set QLineEdit focus in Qt.

QTimer::singleShot(0, line_edit, SLOT(setFocus()));

Before I found that elegant way to set focus I developed my own:

void forceFocus(QWidget* widget)
{
    // unless set active, no stable set focus here
    widget->activateWindow();
    // the event object is released then in event loop (?)
    QFocusEvent* eventFocus = new QFocusEvent(QEvent::FocusIn);
    // posting event for forcing the focus with low priority
    qApp->postEvent(widget, (QEvent *)eventFocus, Qt::LowEventPriority);
}
like image 129
Alexander V Avatar answered Sep 18 '22 15:09

Alexander V


The accepted answer did not work for me. The qApp->focusWidget() is correctly updated, but the caret does not appear. I tried a great deal many variations on things like grabKeyboard(), setReadOnly(), setCursorPosition(), activateWindow(), cursorBackward(), cursorForward(), cursorFlashTime() and so on, but to no avail. They revealed that the cursor was in the right place, just not being drawn.

Not sure how my scenario differs to the OP. Like in Activate cursor in QTextEdit I'm calling setFocus() after responding to another button press but otherwise pretty standard.

Finally, using the clues in the OP, this sledgehammer approach got me there:

QPoint pos(line_edit->width()-5, 5);
QMouseEvent e(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
qApp->sendEvent(line_edit, &e);
QMouseEvent f(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
qApp->sendEvent(line_edit, &f);
like image 33
Heath Raftery Avatar answered Sep 16 '22 15:09

Heath Raftery