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()
构造看起来有点奇怪(但工作正常)。
我刚刚实现了一个 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()
构造看起来有点奇怪(但工作正常)。