//Description: 最近老是遇到不响应信号的问题,做此记录
//Create Date: 2020-06-22 19:17:58
//Author: channy
上述项目中的readAllLabelsInXml部分
原意是想要统计一个文件(许多xml组成)中出现过的label信息
创建了一个ThreadObject类并移到线程中,处理每一行数据,从中提取出label名称并存储在map中
MainWidget用来读取文件内容并调用ThreadObject
m_thread = new QThread();
threadObject = new ThreadObject();
threadObject->moveToThread(m_thread);
connect(this, &MainWidget::sigHasData, threadObject, &ThreadObject::analyse);
QFile file(qsFileName);
if (!file.exists()) {
std::cout << "File " << qsFileName.toStdString().c_str() << " does not exist" << std::endl;
return;
}
int nIdx = 0;
if(file.open(QIODevice::ReadOnly)) {
char buffer[1024];
qint64 lineLen = file.readLine(buffer , sizeof(buffer));
std::cout << "start to read files" << std::endl;
while (lineLen != -1)
{
m_qsBuffer = QString(buffer);
std::cout << "main thread " << QThread::currentThreadId() << std::endl;
QTimer::singleShot(0, this, &MainWidget::sendSig);
lineLen = file.readLine(buffer , sizeof(buffer));
if (++nIdx >= 5) break;
}
}
file.close();
MainWidget中每读取一行内容就调用槽函数发送信号。从log上看信号是发送了,可是ThreadObject没收到呀。。。
没收到信号可能的原因:
类没有继承QObject或没有声明Q_OBJECT 信号或槽函数没有正确定义,没有放到Q_SIGNALS或Q_SLOTS等等下面 信号被子控件过滤掉了 传递参数是自定义的类型且没有register,需要用qRegisterMetaType<类型>("名称")才能作为signal-slot的参数 就是上面这种,emmm......线程没起来~~~哭晕~~~ 对象没有实例化 一般用Qt::QueuedConnection的是异步的,但是偶尔能遇到延迟比较多甚至不响应的情况类型>
为什么moveToThread后还要手工thread->start?
如果不手工start的话,调用该类的函数也会触发start,而信号不会
修改后生效
m_thread = new QThread();
threadObject = new ThreadObject();
threadObject->moveToThread(m_thread);
m_thread->start();
QMetaObject::Connection res = connect(this, &MainWidget::sigHasData, threadObject, &ThreadObject::analyse);
std::cout << "connect res " << (bool)res << std::endl;
QFile file(qsFileName);
if (!file.exists()) {
std::cout << "File " << qsFileName.toStdString().c_str() << " does not exist" << std::endl;
return;
}
int nIdx = 0;
if(file.open(QIODevice::ReadOnly)) {
char buffer[1024];
qint64 lineLen = file.readLine(buffer , sizeof(buffer));
std::cout << "start to read files" << std::endl;
while (lineLen != -1)
{
QString qsBuffer = QString(buffer);
std::cout << "main thread " << QThread::currentThreadId() << std::endl;
QTimer::singleShot(0, this, [this, qsBuffer]{
emit sigHasData(qsBuffer);
});
lineLen = file.readLine(buffer , sizeof(buffer));
if (++nIdx >= 5) break;
}
}
file.close();
并且,connect的最后一个参数ConnectionType也可以影响槽的响应。按官方文档,QueuedConnection槽是运行在接收端的,DirectConnection槽是运行在发送端的。所以如果槽没响应,可能是运行端任务重或是被阻塞了。
背景:调试服务器接口获取数据,写了一个NetworkManager类,把服务器的接口都封装到这个类里面了。
然后在widget里面调用
NetworkManager manager;
QByteArray qsEncodePassword = QCryptographicHash::hash(QByteArray("12345678"), QCryptographicHash::Md5);
manager.login("15732100905", QString(qsEncodePassword));
//manager.logout();
结果:有返回,reply不为空,也没有error,但是槽函数就是不触发。。。
修改manager为指针对象后立马生效!!!
NetworkManager *manager = new NetworkManager(this);
QByteArray qsEncodePassword = QCryptographicHash::hash(QByteArray("12345678"), QCryptographicHash::Md5);
manager->login("15732100905", QString(qsEncodePassword));
//manager.logout();