查看完整版本: [-- 请教一个定时器问题 --]

QTCN开发网 -> Qt基础编程 -> 请教一个定时器问题 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

clickto 2019-10-30 08:45

请教一个定时器问题

我在对话框中使用了如下代码:
QTimer::singleShot(10*1000,[=]{
            ui->frame_op->hide();
            emit sig_user_login(NormalUser);
    });
对话框以指针形式调用,所有我设置了setAttribute(Qt::WA_DeleteOnClose);
现在问题是,如果在定时器到期之前我关闭了窗口,此时ui->frame_op已经被删除了,执行到ui->frame_op->hide();的时候就会出现内存错误了。
请教一下怎么在对话框的析构函数中停止singleShot的定时器?

20091001753 2019-10-30 13:00
两种方法:

  1. connect(ui->buttonA,&QPushButton::clicked,[&]{
        Dialog a;
        a.exec();
    });
    connect(ui->buttonB,&QPushButton::clicked,[&]{
        auto a = new Dialog;
        connect(a,&Dialog::finished,a,&Dialog::deleteLater);
        a->exec();
    });


clickto 2019-10-30 14:10
谢谢版主回复,但是我的问题就是出在这里。
我已经setAttribute(Qt::WA_DeleteOnClose)了,所以不担心资源释放的问题,反而是,窗口关闭时,资源已经释放,但定时器还在执行,等到定时器到期执行函数时,使用到了界面元素,但此时资源已经释放了,所以出现野指针的问题。我想要的效果是,当窗口资源释放时,将还在执行中的定时器也关掉。现在使用QTimer.start()的方式来手动管理,但我的问题就是,使用QTimer::singleShot形式的定时器,在这种情况下应该怎么处理?

hgx123 2019-10-30 15:15
不知道怎么停止
可以用一个标志位,在QTimer::singleShot 触发时去判断这个标志位,判断资源是否已经被释放

20091001753 2019-10-30 17:01
把 QTimer::singleShot 这段代码,放在 Dialog 里。
那么在 Dialog 析构后,connect 自动脱钩。
也就是不会触发。

clickto 2019-10-30 20:31
20091001753:把 QTimer::singleShot 这段代码,放在 Dialog 里。
那么在 Dialog 析构后,connect 自动脱钩。
也就是不会触发。 (2019-10-30 17:01) 

我原先也以为是这样,直到出现野指针问题。
我跟了一下,QTimer::singleShot开始执行后再关闭Dialog,后续走向不确定,有时候Timer会直接关闭,有时候会继续走,直到触发事件,操作原本已经释放的资源,产生野指针问题进而崩溃。

clickto 2019-10-30 20:36
我现在的方案是,不采用QTimer::singleShot + lambda这种形式,而是在Dialog里添加slot函数,通过connect的方式来使用,这样当Dialog析构后,要投递的对象消失,不再响应,从而避免崩溃。
我好奇的是,如果继续使用QTimer::singleShot + lambda这种形式,该如何处理?


查看完整版本: [-- 请教一个定时器问题 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled