QTimer::singleshot(0) lambda 函数调用是否有替代解决方案

Is there an alternative solution for a QTimer::singleshot(0) lambda function call

我刚刚实现了一个 QLineEdit,select 它是获得焦点后的文本。我创建了一个派生的 class 并添加了

virtual void focusInEvent(QFocusEvent *event) override;

到header。我首先尝试像这样实现它:

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

但它不会 select 文本,显然,调用 selectAll() 时某些内容尚未处理。

可行的解决方案是将 selectAll() 调用置于 QTimer::singleShot lambda 调用中,等待 0 秒,如下所示:

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

这样可以在调用 selectAll() 之前处理所有内容,并且一切正常。

这只是一个例子,我已经运行进入这个问题好几次了。所以我想知道是否有一种 pre-defined 方法告诉 Qt "Execute the following, but process everything else before"?

在class定义中,添加代码: signals: void focusIn();

在构造函数中,添加代码: connect(this, &MyLineEdit::focusIn, this, &QLineEdit::selectAll, Qt::QueuedConnection);

在focusInEvent函数中,添加代码: emit this->focusIn();

工作正常!

你可以这样做:

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

不过这是否更好还有待商榷;它也只适用于用 Q_INVOKABLE 声明的插槽和其他可调用对象,而不适用于所有方法。

从文体上来说,我同意你的看法,如果有一个 API 就好了; QTimer::singleShot() 构造看起来有点奇怪(但工作正常)。