Qt如何删除消息循环内的函数

ronal7do 2015-04-20 05:13:51
我在主线程中如下定义;

Worker *worker;
QTimer timer;

然后

worker->moveToThread(Threaddata);

Worker 用来执行一些非常耗时的操作,包括读取数据,计算等,Threaddata是子类化QThread的。
然后

connect(&timer,SIGNAL(timeout()),worker,SLOT(repeatResult()));

基本的代码如上。问题是,当我设置timer的间隔时间比worker的槽函数repeatResult()执行的时间短的时候,当发出timeout信号但repeatResult还在执行,此时新的repeatResult是不是会进入所谓的消息循环等待(??不知道要叫啥),但如果我想

timer.stop();

此时之前等待的repeatResult函数还会继续执行,达不到我想停止计时器的效果。所以我想问有没有个函数可以清除消息循环?
...全文
334 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
大卫无限 2015-04-22
  • 打赏
  • 举报
回复
其实你没有必要在repeatResult里面加入锁,Qt的信号其实就相当于是锁. 为什么这样说呢,现在timer和repeatResult在一个线程里面,按照我的理解,一个线程只会有一个栈顶指针,也就是说一个线程里面不可能有两个函数同时执行.当你的repeatResult,没有执行完成,timeout应该也就不会被执行,因为repeatResult和timeout在一个线程不可能同时执行.这也就是所谓的消息循环,一个一个的循环,必然有先后. 至于信号量大概是这样的,定义一个具有一个资源的信号量, timeout的槽里面去获取,获取到了就调用repeatResult,如果已经获取过一次,第二次执行再去获取,就会获取失败,它就会锁住,信号量是线程级的,这时Timer所在线程就不会动了.在你的repeatResult函数结尾的地方释放资源.这时时候, timeout的槽里锁住的锁会打开,再次执行. 这两种方法其实都是一样的,一个是由Qt自身处理了,一个是由你自己处理了.
ronal7do 2015-04-22
  • 打赏
  • 举报
回复
引用 3 楼 n7zj0x8 的回复:
不知道怎么说了, 写着异步调用的代码,却想达到同步的效果. 要想代码同步调用,可以使用信号量,限制timer的timeout,这样timer不会以准确的时间触发,会等上一次触发完成之后才会触发,效果大概是 timer时间大于repeatResult的时间,会取timer的时间,timer时间小于repeatResult,时间会取repeatResult的时间. 还有就是timer也移动到Threaddata这个里面去.这样timer和repeatResult在一个线程里面,这样就是顺序执行,repeatResult执行的时候,timer就会卡住. 如果上述方法都不是你想要的,你就只能自己写一个队列,自己处理队列.其实到最后和上述方法的效果应该是一样的.
把timer移动到Threaddata后,在主线程如果执行计时器的start或stop时会出现如下警告:

QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread
后来就使用了信号槽来控制计时器的开始和停止

connect(this,SIGNAL(trigTimer()),&guitimer,SLOT(start()));
connect(this,SIGNAL(stopTimer()),&guitimer,SLOT(stop()));
而且在repeatResult函数里面加了

mutex->lock();
......
mutex->unlock();
这样子基本能解决问题。你说的信号量,我看了《C++ GUI Qt4》里的介绍,好像是用来解决生产者和消费者问题的,不知道该怎么用来解决我的这个问题,少侠能否不吝赐教?
大卫无限 2015-04-21
  • 打赏
  • 举报
回复
不知道怎么说了, 写着异步调用的代码,却想达到同步的效果. 要想代码同步调用,可以使用信号量,限制timer的timeout,这样timer不会以准确的时间触发,会等上一次触发完成之后才会触发,效果大概是 timer时间大于repeatResult的时间,会取timer的时间,timer时间小于repeatResult,时间会取repeatResult的时间. 还有就是timer也移动到Threaddata这个里面去.这样timer和repeatResult在一个线程里面,这样就是顺序执行,repeatResult执行的时候,timer就会卡住. 如果上述方法都不是你想要的,你就只能自己写一个队列,自己处理队列.其实到最后和上述方法的效果应该是一样的.
licho.sun 2015-04-20
  • 打赏
  • 举报
回复
不知道有没有清消息的,之前遇到过类似的问题,我是在SLOT响应函数前检查一个标记,然后time.stop()前先改变该标记。 不条例条件就return了。
ronal7do 2015-04-20
  • 打赏
  • 举报
回复
自顶啊!!!

16,240

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧