记录 Qt 跨线程 信号无法触发槽函数问题
Qt项目中多线程通信时 使用connect 连接了两个线程中的信号与槽,槽函数触发不了:
// MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {// 创建线程和串口管理器m_serialThread = new QThread(this);m_serialManager = new SerialManager();// 将对象移动到子线程m_serialManager->moveToThread(m_serialThread);// 连接信号槽,明确指定队列连接connect(m_serialManager, &SerialManager::portsRefreshed,this, &MainWindow::onPortsRefreshed, Qt::QueuedConnection);// 启动线程m_serialThread->start();}
比如上面这样的代码,要通过SerialManager中的信号 触发当前类中的槽函数 onPortsRefreshed;结果就是一直触发不了,上网搜了一下以及问了一下AI,各种原因以及办法试了好久最终解决。
我的问题在于 信号与槽的传递的参数格式非常规,用的是Qt本身的源文件中的QSerialPortInfo类 但是这个类不在标准传参类型之中。
所以有两种解决办法:1.在发出信号之前把需要传递的信息转化为常规类型 比如QString 或者 QVector等,然后用这些类型作为参数;2.使用自定义/非常规类型的参数之前先注册一下比如:
// 自定义类型
struct CustomData {int id;QString name;
};
Q_DECLARE_METATYPE(CustomData)// 在使用前注册
qRegisterMetaType<CustomData>("CustomData");// 信号声明
signals:void customSignal(const CustomData &data);
还有一些其他的原因会导致槽无法触发:比如线程未启动需要调用 thread->start()函数;connect 后面参数未指定 Qt::QueuedConnection ;局部对象生命周期随函数结束的; 还有movetoThread的类无事件循环的(这种情况可能有点复杂)等