问题背景
使用qt编写多线程程序时,报了以下两个崩溃错误:
- ASSERT failure in QArrayData::deallocate: “Static data cannot be deleted”, file tools\qarraydata.cpp, line 269
- ASSERT failure in QWidget: “Widgets must be created in the GUI thread.”, file kernel\qwidget.cpp, line 1007
线程1中有类A,线程2中有类B,类A与类B使用以下槽函数连接:
connect(nvr,&NvrBase::sendNvrRealParam,[=](NvrPlayRealParam param){
省略GUI操作
}}
);
一、问题解决
将槽函数改为connect(nvr,&NvrBase::sendNvrRealParam,this[=](NvrPlayRealParam param){
}}
);
当上述槽函数不加this时,代表槽函数内容在信号所在线程执行,而信号所在线程为非gui线程,qt规定,非gui线程不能操作gui线程,故报错;加上this后,程序在this指向的gui线程中执行,故程序正常运行。
二、跨线程间通讯说明
auto _pollingThread2= new QThread();
auto pollingProgress= new PollingProgress(this);
pollingProgress->moveToThread(_pollingThread2);
//operate信号发射后启动线程工作
connect(this, SIGNAL(pollingProgress(long,OPERATE)), pollingProgress, SLOT(startPollingProgress(long,OPERATE)));
//该线程结束时销毁
connect(_pollingThread2, &QThread::finished,[=]{_pollingThread2->exit(0);delete pollingProgress;delete _pollingThread2;}); //pollingProgress, &QObject::deleteLater);
_pollingThread2->start();
_threadQuit=false;
emit this->pollingProgress(_hDownload,OPERATE::DOWNLOAD);
当槽函数中出现自定义变量时,应加以声明,才能在跨线程间被识别(信号发出线程和信号接收线程是两个线程),声明方法为:
Q_DECLARE_METATYPE(自定义类);
再在信号调用前:
qRegisterMetaType(“自定义类”);
即可使用跨线程信号
二、附:Switch的用法
while(finished){
switch(downloadPos)
{
case -1:
{
Sleep(100);
break;
}
case 200:
{
qDebug()<<"下载网络异常情况";
//finished=true;
Sleep(100);
break;
}
case 100:
{
qDebug()<<"下载完成";
finished=true;
//下载后重命名
QFile::rename(nvr->_pathName+".temp",nvr->_pathName+".dav");
nvr->stopdownLoad();
nvr->downloadFinished();
break;
}
default:
;
}}
其中default等同于else,每个case和case间中需要用括号括起来,形成复合语句,如果想在swith中跳出外层循环,只能使用变量,如上图中的//finished=true;