通过Lambda和递归函数调用了解QTimer [英] Understanding QTimer with Lambda and recursive function call

查看:176
本文介绍了通过Lambda和递归函数调用了解QTimer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

void class::Testfunc()
{
    QTimer* timer = new QTimer;
    QObject::connect(timer, &QTimer::timeout, [this](){
        emit Log("Time out...");
        TestFunc(serverAddress, requestsFolderPath);
       // deleteLater(); //*** why does this crash if used to replace the connect below?
    });
    connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);
    timer->setSingleShot(true);
    timer->start(1000);
}

创建一个单发计时器,其timout连接到记录的lambda函数每秒进入lambda函数的入口(将文本打印到stdout)并再次调用该函数。

A single shot timer is created with a timout connected to a lambda function that logs the entrance to the lambda function each second (prints text to stdout) and calls the function again.

此方法没有问题。但是,如果我删除了对deleteLater的连接调用(在lambda函数下面),但是在lambda函数中启用了deleteLater调用,则该函数将失败。它将立即打印一次,并在尝试删除计时器对象时崩溃。

This works without issue. However, if I remove the connect call to deleteLater (below the lambda function), but enable the deleteLater call in the lambda function, the function fails. It prints once and shortly after, crashes in trying to delete the timer object.

在此实例中,两个deleteLater调用之间有什么区别?为什么将deleteLater放入lambda函数在这里引起问题,而创建单独的连接却按预期工作,即使两者都响应计时器的超时信号而调用deleteLater吗?

What is the difference between the two deleteLater calls in this instance and why would placing the deleteLater in the lambda function cause a problem here, whereas creating a separate connection works as expected, even though both are calling deleteLater in response to the Timer's timeout signal?

推荐答案

鉴于没有错字或我不知道的某些信息,我认为原因是因为您正在尝试删除您的实例而不是使用上述方法在堆上分配的 QTimer 实例。

Given that there is no typo or some information that I am not aware of, I think the reason is that because you are trying to delete your class instance later rather than the QTimer instance allocated on the heap in the aforementioned method.

如果您查看非lambda版本,它在 QTimer实例上调用 deleteLater ,因为它是connect调用中的接收者。

If you take a look at the the non-lambda version, that calls the deleteLater on the QTimer instance as that is the receiver in the connect call.

connect(timer, &QTimer::timeout, timer, &QTimer::deleteLater);

但是,在lambda变体中,不会捕获计时器实例,自然也就无法访问分别以当前版本对其进行修改。为了使两个替代方案等效,需要对代码进行以下修改:

However, in the lambda variant, the timer instance is not captured and naturally, there would be no access to it in its current version, respectively. To make the two alternatives equivalent, this modification needs to be done to the code:

QObject::connect(timer, &QTimer::timeout, [this, timer](){
//                                               ^^^^^
    emit Log("Time out...");
    TestFunc(serverAddress, requestsFolderPath);
    timer->deleteLater();
//  ^^^^^^^
});

这篇关于通过Lambda和递归函数调用了解QTimer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆