简单的测试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中的②部分,在次线程中执行主线程对象的一些操作引起的 。
解决方法:如果次线程需要更新主线程对象状态,需要发送消息,主线程对象接收后处理而不能在此线程中直接操作。
使用定时器注意事项:
①不能跨线程启动定时器和停止定时器;
②不能跨线程启动一个定时器关联的对象,但在另一个线程释放;
③定时器相关的逻辑和对象只能用在一个线程中。