Reputation: 1722
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"?
Upvotes: 0
Views: 830
Reputation: 1997
Since Qt 5.10 (this commit) you can do QMetaObject::invokeMethod(this, &QLineEdit::selectAll, Qt::QueuedConnection);
I think it's better than a 0s single-shot timer because you don't have to register a temporary timer, invokeMethod just posts an event.
Upvotes: 1
Reputation: 21
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!
Upvotes: 1
Reputation: 306
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).
Upvotes: 0