• 1994阅读
  • 6回复

请教一个定时器问题 [复制链接]

上一主题 下一主题
离线clickto
 

只看楼主 倒序阅读 楼主  发表于: 2019-10-30
我在对话框中使用了如下代码:
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

只看该作者 1楼 发表于: 2019-10-30
两种方法:

  1. connect(ui->buttonA,&QPushButton::clicked,[&]{
  2.     Dialog a;
  3.     a.exec();
  4. });
  5. connect(ui->buttonB,&QPushButton::clicked,[&]{
  6.     auto a = new Dialog;
  7.     connect(a,&Dialog::finished,a,&Dialog::deleteLater);
  8.     a->exec();
  9. });

(づ ̄ 3 ̄)づ
离线clickto

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

只看该作者 3楼 发表于: 2019-10-30
不知道怎么停止
可以用一个标志位,在QTimer::singleShot 触发时去判断这个标志位,判断资源是否已经被释放
在线20091001753

只看该作者 4楼 发表于: 2019-10-30
把 QTimer::singleShot 这段代码,放在 Dialog 里。
那么在 Dialog 析构后,connect 自动脱钩。
也就是不会触发。
(づ ̄ 3 ̄)づ
离线clickto

只看该作者 5楼 发表于: 2019-10-30
回 20091001753 的帖子
20091001753:把 QTimer::singleShot 这段代码,放在 Dialog 里。
那么在 Dialog 析构后,connect 自动脱钩。
也就是不会触发。 (2019-10-30 17:01) 

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

只看该作者 6楼 发表于: 2019-10-30
我现在的方案是,不采用QTimer::singleShot + lambda这种形式,而是在Dialog里添加slot函数,通过connect的方式来使用,这样当Dialog析构后,要投递的对象消失,不再响应,从而避免崩溃。
我好奇的是,如果继续使用QTimer::singleShot + lambda这种形式,该如何处理?
快速回复
限100 字节
 
上一个 下一个