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

时间:2018-08-12 09:05:34

标签: qt lambda qtimer qeventloop

我刚刚实现了QLineEdit,它在获得焦点之后立即选择了文本。我创建了派生类并添加了

virtual void focusInEvent(QFocusEvent *event) override;

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

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

但是它不会选择文本,显然,在调用selectAll()时尚未处理某些东西。

有效的解决方案是将selectAll()调用放入QTimer::singleShot lambda调用中,等待时间为0秒,如下所示:

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

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

这只是一个例子,我已经多次遇到这个问题。因此,我想知道是否存在一种预定义的方法来告诉Qt“执行以下操作,但之前先处理其他所有内容”?

2 个答案:

答案 0 :(得分:1)

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

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

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

做得好!

答案 1 :(得分:0)

您可以这样做:

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

这是否更好还值得商;;它也仅适用于用Q_INVOKABLE声明的广告位和其他可调用项,不适用于所有方法。

通常,我同意您的看法,为此拥有一个API会很好。 QTimer::singleShot()的结构看起来有些奇怪(但效果很好)。