QTimer在非QThread的环境下能正常工作。但在QThread环境下,需要做一些改动才能正常工作。

创建Qt的线程有两种方式:

1. 子例化QThread

可以在虚函数run中启动定时器,大致的代码如下:

//构造函数,继承QThread
Thread::Thread(QObject *parent)
: QThread(parent)
{ } void Thread::run()
{
QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用
connect(timer, SIGNAL(timeout()), this, SLOT(display()));
timer->start();
exec(); //开启事件循环
} //调用,启动线程
Thread* thread = new Thread; //此处设父指针为this,关闭应用程序时会发生崩溃
thread->start();

两处指针new的时候不能加this指针,run函数中必须加exec函数。

很不理解Qt为什么会这么干???

2. 继承QObject,使用moveToThread移入线程

大致的代码如下:

Calc::Calc(int start, int step)
: m_cur(start)
, m_step(step)
{
QThread* thread = new QThread;
moveToThread(thread);
thread->start(); QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用
connect(timer, SIGNAL(timeout()), this, SLOT(display()));
timer->start();
} Calc* c = new Calc(, );

构造函数内两处指针new的时候,也不能加this

具体的代码如下:

#ifndef WIDGET_H
#define WIDGET_H #include <QWidget>
#include <QThread> QT_BEGIN_NAMESPACE class QTimer;
class Thread; class Widget : public QWidget
{
Q_OBJECT public:
Widget(QWidget *parent = );
~Widget();
}; class Thread : public QThread
{
Q_OBJECT
public:
Thread(QObject* parent = nullptr); public slots:
void display(); protected:
void run();
}; class Calc : public QObject
{
Q_OBJECT
public:
Calc(int start, int step); public slots:
void display(); private:
int m_cur;
const int m_step;
}; QT_END_NAMESPACE #endif // WIDGET_H #include "widget.h" #include <QTimer>
#include <QDebug> Widget::Widget(QWidget *parent)
: QWidget(parent)
{
/*
Thread* thread = new Thread; //此处设父指针为this,关闭应用程序时会发生崩溃
thread->start();
*/ Calc* c = new Calc(, );
Q_UNUSED(c);
} Widget::~Widget()
{ } //构造函数,继承QThread
Thread::Thread(QObject *parent)
: QThread(parent)
{ } void Thread::display()
{
qDebug() << "running in thread";
} void Thread::run()
{
QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用
connect(timer, SIGNAL(timeout()), this, SLOT(display()));
timer->start();
exec(); //开启事件循环
} Calc::Calc(int start, int step)
: m_cur(start)
, m_step(step)
{
QThread* thread = new QThread;
moveToThread(thread);
thread->start(); QTimer* timer = new QTimer; //多线程环境中,此处设父指针为this,会导致创建线程失败,定时器可用
connect(timer, SIGNAL(timeout()), this, SLOT(display()));
timer->start();
} void Calc::display()
{
qDebug() << m_cur;
m_cur += m_step;
}

QTimer在QThread环境中失效的问题的更多相关文章

  1. spring事务在web环境中失效的问题

    今天温习一下spring事务的时候,出现了一种诡异的现象,在java环境中测试事务是可以的.然后到web下测试事务就没用了.spring.xml配置 spring-mvc.xml配置 后来百度发现是因 ...

  2. 在不开启事件循环的线程中使用QTimer(QThread::run函数自带事件循环,在构造函数里创建线程,是一种很有意思的线程用法) good

    引入 QTimer是Qt自带的定时器类,QTimer运行时是依赖于事件循环的,简单来说,在一个不开启事件循环(未调用exec() )的线程中,QTimer是无法使用的.通过分析Qt源码可发现,调用QT ...

  3. SQL优化:清理生产环境中已失效字段基本步骤

    1.统计相应字段的数据情况(如:几年没更新,无数据等情况) 2.确认产品逻辑已无效(产品经理邮件确认) 3.数据备份 4.将数据清空(置为0或空) 5.测试环境中删除引用页面 6.修改定时程序,存储过 ...

  4. ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据

    引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们 ...

  5. Bug2算法的实现(RobotBASIC环境中仿真)

    移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不 ...

  6. 【原】Storm Local模式和生产环境中Topology运行配置

    Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...

  7. 在多任务(RTOS)环境中使用看门狗

    最近在SEGGER的博客上看到一篇有关在实时操作系统使用看门狗的文章.从一个失败的太空项目出发,分析了看门狗的作用及使用,自我感觉很有启发,特此翻译此文并推荐给各位同仁.为了阅读方便,有些航天领域名词 ...

  8. 【Zookeeper系列】ZooKeeper管理分布式环境中的数据(转)

    原文地址:https://www.cnblogs.com/sunddenly/p/4092654.html 引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它 ...

  9. ZooKeeper系列(5):管理分布式环境中的数据

    引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知 识,理解起来比较抽象所以还需要借助一些应用场景,来帮我 ...

随机推荐

  1. Webapck项目开发基本构建及配置

    1.创建项目文件夹 myapp 手动创建myapp,或mkdir myapp 2.cd myapp 3.npm init (初始化项目) 4.一路回车(关于项目信息的填写,可以不写,一路回车即可) 可 ...

  2. C#中的var和dynamic

    在理解var和dynamic关键字之前,让我们先了解一下编程语言的类别. C#中有两类编程语言: 静态类型语言类别 动态语言类别 静态类型语言 静态类型语言也被称为强类型语言.所谓强类型语言,通俗的讲 ...

  3. MySQL 8 新特性之Invisible Indexes

    背景 索引是把双刃剑,在提升查询速度的同时会减慢DML的操作.毕竟,索引的维护需要一定的成本.所以,对于索引,要加上该加的,删除无用的.前者是加法,后者是减法.但在实际工作中,大家似乎更热衷于前者,而 ...

  4. Day6_内置函数

    定义完一个有名函数,可以直接利用函数名+括号来执行,例如:func() 有名函数: def func(x,y,z=1): return x+y+z 匿名函数: lambda x,y,z=1:x+y+z ...

  5. Ocelot中文文档-不支持

    Ocelot不支持一下几点... 分块编码 - Ocelot将始终获取body大小并返回Content-Length头. 如果这不适合你的场景,只能表示抱歉! 转发host头 - 您发给Ocelot的 ...

  6. Java虚拟机-内存tips

    java虚拟机内存可以分为独占区和共享区. 独占区:虚拟内存栈.本地方法栈.程序计数器. 共享区:方法区.Java堆(用来存放对象实例). 程序计数器 比较小的内存空间,当前线程所执行的字节码的行号指 ...

  7. 通过Django Channels设计聊天机器人WEB框架

    这两个月都在忙着设计针对银联客服业务的智能聊天机器人,上一周已经交完设计报告,这一周还和部门同事一起分享了系统设计及运行效果.因为时间的关系,系统原型我使用了Flask+jQuery的组合,感觉用以原 ...

  8. javascript封装的参数合并

    o=$.extend(initializationInterface.defaultValue,o); o= $.extend({}, initializationInterface.prototyp ...

  9. 学习JavaScript最佳实践方法

    首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这个时候有人要说,“靠,你丫半桶水,凭啥教我们”.您先别急着骂,先听我说. 你叫一个大学生去教小学数 ...

  10. java 一维数组

    数组的概念?有什么特点? 数组是指一组数据的集合,数组中的每个数据被称作元素.在数组中可以存放任意类型的元素,但同一个数组里存放的元素类型必须一致. 一维数组的定义格式? 数据类型[]   名称  = ...