6

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?

spraff
  • 32,570
  • 22
  • 121
  • 229
  • After you show the dialog, which widget gets the focus? You can check with GammaRay / `QApplication`. – peppe Mar 03 '16 at 12:16

2 Answers2

2

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);
}
Community
  • 1
  • 1
Alexander V
  • 8,351
  • 4
  • 38
  • 47
  • That works, although the reason cited in your link is dubious: *"Keyboard focus is related to widget tab order, and the default tab order is based on the order in which widgets are constructed. Therefore, creating more widgets changes the keyboard focus. That is why you must make the QWidget::setFocus call last."* -- I was calling setFocus () at the end of construction, after all widgets had been created and added. Something else is going on. – spraff Mar 03 '16 at 17:12
  • Correct and that is how many stackoverflow pages are written by people. Everything needs to be proven in practice, so many inaccurate statements. – Alexander V Mar 03 '16 at 17:30
1

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);
Community
  • 1
  • 1
Heath Raftery
  • 3,643
  • 17
  • 34