• 290阅读
  • 21回复

[提问]Qt的多线程是不是不能使用QTimer [复制链接]

上一主题 下一主题
离线wcrqpdb
 

只看楼主 倒序阅读 楼主  发表于: 11-06
会报这个  QObject::startTimer: Timers cannot be started from another thread
离线沉默小ai

只看该作者 1楼 发表于: 11-06
可以使用,这个提示是你跨线程操作QTimer了 这个是不允许的
离线wcrqpdb

只看该作者 2楼 发表于: 11-07
但这个QTimer我是在继承QThread这个类里创建的吖,在.h声明.cpp构造函数里创建
离线uidab

只看该作者 3楼 发表于: 11-07
回 wcrqpdb 的帖子
wcrqpdb:但这个QTimer我是在继承QThread这个类里创建的吖,在.h声明.cpp构造函数里创建 (2019-11-07 01:49)

那就不对了,继承QThread只有在run中是另外一个线程,其他定义都属于主线程。

看看movetothread吧
有时候为了工作直接获得答案,而我却失去了思考的乐趣!


飘啊飘,何时能安居!
离线wcrqpdb

只看该作者 4楼 发表于: 11-07
我见网上教程说有2种方法创建,第一种用一个类继承QThread,然后重新改写虚函数run()。当要开启新线程时,只需要实例该类,然后调用函数start(),就可以开启一条多线程。第二种方法是继承一个QObject类,然后利用moveToThread()函数开启一个线程槽函数,将要花费大量时间计算的代码放入该线程槽函数中。我是用第一种的,你说用movetothread那是第二中的。那用第一种方法要怎么用QTimer
网上教程https://blog.csdn.net/naibozhuan3744/article/details/81174681

离线沉默小ai

只看该作者 5楼 发表于: 11-07
你实在是想用继承QThread的方式的话,把QTimer 的对象在run函数内创建,这样这个QTimer就属于这个线程了,继承的Qthread的类的创建、构造函数的实际上还是由 创建 继承的Qthread的类 的线程操作的。
离线wcrqpdb

只看该作者 6楼 发表于: 11-07
回 沉默小ai 的帖子
沉默小ai:你实在是想用继承QThread的方式的话,把QTimer 的对象在run函数内创建,这样这个QTimer就属于这个线程了,继承的Qthread的类的创建、构造函数的实际上还是由 创建 继承的Qthread的类 的线程操作的。[表情] [表情] [表情]  (2019-11-07 11:23) 

在run内创建也不行,报QObject: Cannot create children for a parent that is in a different thread.
(Parent is readWriteThread(0x21080b80), parent's thread is QThread(0x20fd2530), current thread is readWriteThread(0x21080b80)

离线angelus

只看该作者 7楼 发表于: 11-07
回 wcrqpdb 的帖子
wcrqpdb:在run内创建也不行,报QObject: Cannot create children for a parent that is in a different thread.
(Parent is readWriteThread(0x21080b80), parent's thread is QThread(0x20fd2530), current thread is readWriteThread(0x21080b80)
 (2019-11-07 11:32) 

这个报错应该和qtimer无关,QTimer是可以直接实例化在run函数内,不过建议把QTimer包含进一个类中,所有run 中运行的逻辑都在这个类中实现,这样,run函数会很干净,多线程操作也会很有条理性
离线圣域天子

只看该作者 8楼 发表于: 11-07
Qt大量控件都存在这个跨线程问题,只能在单个线程中使用。
离线uidab

只看该作者 9楼 发表于: 11-07
回 angelus 的帖子
angelus:这个报错应该和qtimer无关,QTimer是可以直接实例化在run函数内,不过建议把QTimer包含进一个类中,所有run 中运行的逻辑都在这个类中实现,这样,run函数会很干净,多线程操作也会很有条理性 (2019-11-07 11:39) 

有时候为了工作直接获得答案,而我却失去了思考的乐趣!


飘啊飘,何时能安居!
离线uidab

只看该作者 10楼 发表于: 11-07
回 wcrqpdb 的帖子
wcrqpdb:在run内创建也不行,报QObject: Cannot create children for a parent that is in a different thread.
(Parent is readWriteThread(0x21080b80), parent's thread is QThread(0x20fd2530), current thread is readWriteThread(0x21080b80)
 (2019-11-07 11:32) 

没代码不好评论,记住这种方式只有在run()中的才是另一个线程。所以你的QTimer变量也只能在这里实例化。很多人是在继承QThread的类定义了QTimer的成员变量,以为这个也是在另一个线程,其实不是。
有时候为了工作直接获得答案,而我却失去了思考的乐趣!


飘啊飘,何时能安居!
离线wcrqpdb

只看该作者 11楼 发表于: 11-07
zi.h

zu.h

main

zi.cpp

zu.cpp
[attachment=21040]
QObject: Cannot create children for a parent that is in a different thread.
(Parent is zi(0x7cf9c0), parent's thread is QThread(0x176f60), current thread is zi(0x7cf9c0)
原程序 a1.rar (5 K) 下载次数:1
离线圣域天子

只看该作者 12楼 发表于: 11-07
QTimer 在线程中不要用 new
QTimer k; 就可以了。run结束后它自动释放。

不过 k 如果关联信号的话,应该依旧会存在。

你的需求的实现方式应该调整一下,在线程中使用 QTimer 发时间信号,应该是没意义了。

离线wcrqpdb

只看该作者 13楼 发表于: 11-07
回 圣域天子 的帖子
圣域天子:QTimer 在线程中不要用 new
QTimer k; 就可以了。run结束后它自动释放。
不过 k 如果关联信号的话,应该依旧会存在。
....... (2019-11-07 16:35) 

我要定时处理数据
离线dbzhang800

只看该作者 14楼 发表于: 11-07
回 wcrqpdb 的帖子
wcrqpdb:zi.h
[图片]
zu.h
[图片]
main
....... (2019-11-07 15:02) 

你在run()内写下列代码,错了。run()函数内是次线程,但是this不在次线程内,不能作为父对象。
new QTimer(this)

另外,run() 内没有 exec()函数,只把timer创建放到run内也没有意义,你代码中的槽函数又不在你的run内执行
离线wcrqpdb

只看该作者 15楼 发表于: 11-07
回 dbzhang800 的帖子
dbzhang800:你在run()内写下列代码,错了。run()函数内是次线程,但是this不在次线程内,不能作为父对象。
new QTimer(this)
另外,run() 内没有 exec()函数,只把timer创建放到run内也没有意义,你代码中的槽函数又不在你的run内执行 (2019-11-07 19:00)

要怎么写,麻烦写一下,上面有原程序
离线angelus

只看该作者 16楼 发表于: 11-08
回 wcrqpdb 的帖子
wcrqpdb:要怎么写,麻烦写一下,上面有原程序
 (2019-11-07 19:38) 

写个独立的处理类,然后在里边按平时的习惯定义qtimer,和处理任务,然后把这个类实例化到run函数内,开启线程循环,至于主线程和次线程通讯,直接信号和thread中的连接上就行,这种信号通知属于跨线程信号槽,异步操作
离线wcrqpdb

只看该作者 17楼 发表于: 11-09
回 angelus 的帖子
angelus:写个独立的处理类,然后在里边按平时的习惯定义qtimer,和处理任务,然后把这个类实例化到run函数内,开启线程循环,至于主线程和次线程通讯,直接信号和thread中的连接上就行,这种信号通知属于跨线程信号槽,异步操作 (2019-11-08 09:15) 

按照你的方法还是报 QObject::startTimer: Timers cannot be started from another thread
离线clickto

只看该作者 18楼 发表于: 11-09
在run的while里sleep啊,达到timer的效果
离线yanwuyue

只看该作者 19楼 发表于: 11-11
继承的不要带this,直接qtimer(),并且实例化的k也只能在run里面使用或者信号控制
离线巫添良

只看该作者 20楼 发表于: 11-11
    up_timer = new QTimer;
    up_timer->setInterval(1000);
    up_timer->start();
    up_timer->moveToThread(&up_img_Thread);//定时器移到子线程中
    connect(up_timer, SIGNAL(timeout()), this, SLOT(up_model_file()), Qt::DirectConnection);
    connect(this, SIGNAL(stop_up_timer()), up_timer, SLOT(stop()));
    connect(this,SIGNAL(start_up_timer()),up_timer,SLOT(start()));
    up_img_Thread.start();
这样写 定时器的槽函数就是在子线程中执行的

离线dbzhang800

只看该作者 21楼 发表于: 前天 17:43
回 巫添良 的帖子
巫添良:    up_timer = new QTimer;
    up_timer->setInterval(1000);
    up_timer->start();
    up_timer->moveToThread(&up_img_Thread);//定时器移到子线程中
   &n .. (2019-11-11 22:49) 

多线程环境使用使用 Qt::DirectConnection ,通常暗示着存在设计问题
快速回复
限100 字节
 
上一个 下一个