0

I just implemented a QLineEdit that selects it's text right after getting focus. I created a derived class and added

virtual void focusInEvent(QFocusEvent *event) override;

to the header. I first tried to implement it like so:

void MyLineEdit::focusInEvent(QFocusEvent *event)
{
    QLineEdit::focusInEvent(event);
    selectAll();
}

but it wouldn't select the text, as apparently, some stuff wasn't processed yet at the time selectAll() is called.

The working solution is to put the selectAll() call in a QTimer::singleShot lambda call with 0 seconds to wait like so:

void MyLineEdit::focusInEvent(QFocusEvent *event)
{
    QLineEdit::focusInEvent(event);
    QTimer::singleShot(0, [this]() { selectAll(); } );
}

This lets everything be processed before selectAll() is invoked and everything works fine.

This is only one example, I already ran into this problem several times. So I wonder if there's a pre-defined method of telling Qt "Execute the following, but process everything else before"?

Tobias Leupold
  • 1,512
  • 1
  • 16
  • 41

2 Answers2

1

in the class define, add the code: signals: void focusIn();

in the constructor function, add the code: connect(this, &MyLineEdit::focusIn, this, &QLineEdit::selectAll, Qt::QueuedConnection);

in the focusInEvent function, add the code: emit this->focusIn();

work fine!

Saber
  • 11
  • 2
  • Thanks for the info! But the question was not about that specific case with the "select on focus" problem, but about the general way to go for such a case. – Tobias Leupold Aug 13 '18 at 07:43
0

You could do this:

QMetaObject::invokeMethod(this, "selectAll", Qt::QueuedConnection);

It is debatable whether this is nicer though; also it only works for slots and other invokables declared with Q_INVOKABLE and not for all methods.

Stylistically I agree with you that it would be nice to have an API for this; the QTimer::singleShot() construct looks a bit strange (but works fine).

Peter Ha
  • 321
  • 2
  • 6
  • Thanks for the info! It was only about whether or not this is one possible or the way to go. But apparently, Qt doesn't provide another method as of now. Well, after all, it works with the `QTimer::singleShot` method. – Tobias Leupold Aug 13 '18 at 07:41