当前位置: 代码迷 >> QT开发 >> 在子线程中讫timer方法,及exec()的疑惑
  详细解决方案

在子线程中讫timer方法,及exec()的疑惑

热度:97   发布时间:2016-04-25 03:17:01.0
在子线程中起timer方法,及exec()的疑惑
    项目中需要串口通讯,我寻思着把需要起QTImer频繁下发的指令放到一个通讯线程里,
结果是这样实现的:
线程类:
原来这么写的run函数,(线程类里除了run函数,其他函数基本都是空的,不需要列出。。)

//构造
CommThread::CommThread(QObject* receiver) :
        QThread(receiver), m_pQueryTimer(NULL),
        m_pADQueryTimer(NULL), m_bTimerFlag(true),
        m_receiver(receiver)
{
//    qDebug() << "CommThread :" << m_receiver.data()->objectName();
}
//run
void CommThread::run()
{
    m_pADQueryTimer = new QTimer;
    m_pQueryTimer = new QTimer;             
    m_pQueryTimer->start(1200);
    m_pADQueryTimer->start(3000);
    connect(m_pQueryTimer, SIGNAL(timeout()), 
m_receiver.data(), SLOT(slotSendStatusQueryCmd()));
    connect(m_pADQueryTimer, SIGNAL(timeout()), 
m_receiver.data(), SLOT(slotSendBStatusQueryCmd()));
    exec();
}

        这样时,信号和槽可以通信,后来因为需要控制两个Timer的启动,所以用循环和变量来写run函数,而把原来的exec()函数去掉了
void CommThread::run()
{
    m_pADQueryTimer = new QTimer;
    m_pQueryTimer = new QTimer;             
    if(!m_receiver.isNull())
    {
        connect(m_pQueryTimer, SIGNAL(timeout()), m_receiver.data(), 
SLOT(slotSendStatusQueryCmd()),Qt::QueuedConnection);
        connect(m_pADQueryTimer, SIGNAL(timeout()), m_receiver.data(), 
SLOT(slotSendBStatusQueryCmd()),Qt::QueuedConnection);
    }

    forever
    {
        if(m_bSendQueryFlag)
        {
            qDebug()<<"m_pQueryTimer start...";
            m_pQueryTimer->start(1200);
            m_pADQueryTimer->start(3000);
        }
        if(m_pADQueryTimer->isActive() && !m_bSendQueryFlag)
        {
            qDebug()<<"m_pQueryTimer stop...";
            m_pQueryTimer->stop();
            m_pADQueryTimer->stop();
        }
    }
//    exec();
}

结果新需求后,发送的Timeout信号就传递不到槽函数中了。。。
有些不明白,exec的作用,如果想用变量控制timer的启动停止,应该如何用循环呢?
------解决方案--------------------
对于串口和QTimer这两个慢速的东西,应该完全没必要再单独开线程。

至于QThread的问题,简单几句话不可能回答你的问题,你可以先看看
http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/



------解决方案--------------------
前段时间也刚好碰到过,首先Qt的信号和槽,还有定时器都是基于Qt的事件循环的,而exec()实际上就是启动了一个事件循环,main()函数里面就可以很明显的看到,所以子线程要接收主线程发的信号,就一定要有自己的事件循环,否则槽函数是不能触发的。
  相关解决方案