QT多线程:定时器QTimer和线程QThread常见报错问题

简单的测试demo:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    
    //按钮的创建以及槽函数连接
    m_pStartBut = new QPushButton("start",this);
    m_pStartBut->setGeometry(0,0,100,50);
    m_pEndBut = new QPushButton("END",this);
    m_pEndBut->setGeometry(0,60,100,50);

    connect(m_pStartBut,&QPushButton::clicked,[&]()
    {
        m_pTimer = new QTimer;
        m_pThread = new QThread;
        connect(this, SIGNAL(stop()), m_pTimer, SLOT(stop()),Qt::BlockingQueuedConnection);

        m_pTimer->start(2000); //①部分
        m_pTimer->moveToThread(m_pThread);
        
        //m_pTimer->moveToThread(m_pThread);//错误
        //m_pTimer->start(2000); //错误

        connect(m_pTimer,&QTimer::timeout,[&]()
        {
           qDebug()<<"发送数据";
        });

        m_pThread->start();

    });
    connect(m_pEndBut,&QPushButton::clicked,[&]()
    {
        if(!m_pThread->isFinished())
        {
            
            //m_pTimer->stop(); //错误

            emit stop();//②部分
            if(!m_pTimer->isActive())
            {
                delete m_pTimer;
                m_pTimer = nullptr;
            }
            //退出线程,再删除
            m_pThread->quit();
            m_pThread->wait();
            delete m_pThread;
            m_pThread = nullptr;
            qDebug()<<"exit pthread!";
        }
    });

}


error1:QObject::startTimer: Timers can only be used with threads started with QThread

问题在于demo中的①部分,定时器timer->start(2000)  必须放在timer->moveToThread(pthread)之前,相反则会报以上错误。

error2: QObject::killTimer: Timers cannot be stopped from another thread
                QObject::~QObject: Timers cannot be stopped from another thread


 问题在于demo中的②部分,在次线程中执行主线程对象的一些操作引起的 。

解决方法:如果次线程需要更新主线程对象状态,需要发送消息,主线程对象接收后处理而不能在此线程中直接操作。

 

使用定时器注意事项:

①不能跨线程启动定时器和停止定时器;

②不能跨线程启动一个定时器关联的对象,但在另一个线程释放;

③定时器相关的逻辑和对象只能用在一个线程中。

 

你可能感兴趣的:(Qt)