【问题标题】:Is there an alternative solution for a QTimer::singleshot(0) lambda function callQTimer::singleshot(0) lambda 函数调用是否有替代解决方案
【发布时间】:2019-01-19 07:11:12
【问题描述】:

我刚刚实现了一个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“执行以下,但之前处理其他所有内容”?

【问题讨论】:

  • 我知道这是唯一的方法,但我可以使用更易读的方法:QTimer::singleShot(0, this, &QLineEdit::selectAll);
  • 我们这里实际上不需要 lambda,谢谢提示 :-)
  • 我认为你需要它,但你不想要它。 ;)
  • 我不想要 QTimer ...
  • 你为什么不想要它?你有什么问题吗?

标签: qt lambda qtimer qeventloop


【解决方案1】:

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

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

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

工作正常!

【讨论】:

  • 感谢您的信息!但问题不在于“选择焦点”问题的具体案例,而是针对此类案例的一般方法。
【解决方案2】:

你可以这样做:

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

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

在风格上我同意你的观点,如果有一个 API 会很好; QTimer::singleShot() 构造看起来有点奇怪(但工作正常)。

【讨论】:

  • 感谢您的信息!这只是关于这是否是一种可能或要走的路。但显然,Qt 目前还没有提供另一种方法。好吧,毕竟它适用于QTimer::singleShot 方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多