QT信号槽的跨线程连接
来源:互联网 发布:如何建立阿里云服务器 编辑:程序博客网 时间:2024/05/22 03:09
QT中的线程可以通过继承QThread类,重写run() 函数,run() 函数即新线程的入(通过start() 函数启动新线程);我我们实现的这个QThread的派生类,只不过是用来管理线程的。run()函数返回,新线程结束,可以在调用 .exec() 函数,在新线程中也开启时间循环。
继承自QObject的对象都会有一个线程依附性,QObject 对象的线程依附性即是创建QObeject对象的线程,可以用 .thread() 函数获得,在QThread对象 的run() 函数中所创建的对象的依附于该QThread 对象,也就是需要通过该QThread 对象来管理。
在QT5中,信号可以连接到一切可以调用的对象上,包括普通函数,成员函数,函数对象,lambda表达式;总的来说,信号与槽的连接有两种方式:1、直接连接 2、队列连接;默认的自动连接下,如果发射信号的线程(而不是发送者所在的线程)与接受者所驻足的线程相同,则是队列连接;如果发送信号的线程与接收者所驻足的不在一个线程,则是队列连接。直接连接下,槽函数在发送信号的线程中立即执行;队列连接情况下,槽函数在接收者所在的线程时间循环处理到时,才执行。
qDebug() << QThread::currentThreadId() << "mainThread";connect(portThread1,&SerialThread::openSuccessSig,[this] { qDebug() << QThread::currentThreadId() << "subThread"; this->openFlag1 = true; this->ui->pushButton_10->setText("关闭"); this->ui->lineEdit_5->setDisabled(true); connect(this, SIGNAL(writeSig1(QByteArray)), portThread1, SIGNAL(myWrite(QByteArray))); //发送数据 并在发送完毕之后发送完毕信号 connect(portThread1, SIGNAL(transFinWSig()), this, SLOT(finWSlots1())); //关闭串口 并在关闭之后发回已经关闭的确认信号 connect(this, SIGNAL(toCloseCom1()), portThread1, SIGNAL(toCloseCom())); connect(portThread1, SIGNAL(finCloseCom()),this, SLOT(closedCom1())); connect(portThread1, SIGNAL(transCode(QString)), this, SLOT(getReadDate1(QString))); });这里SerialThread 用来管理子线程,信号currentThreadId() 从子线程中发送过来;构建运行,发生ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 15bb2fd0. Receiver 'lineEdit_5' (of type 'QLineEdit') was created in thread 13fd3478"
的错误,说是lineEdit_5所在的线程与lambda 表达式函数体中所在的线程不同;于是在代码中加入三个qDebug() 语句,打印当前的线程id, 结果发现,lambda 函数体中的线程id 与 SerialThread的run() 函数中输出的线程id() 相同,也就是说,对于lambda 表达式,其执行的线程为信号发送的线程。
解决的办法:想办法使信号从主线程发送过来即可,在SerialThread的run() 函数中, 发送openSuccessSig() 信号的地方改为发送一个新的信号openSuccess() , 新的信号跟新创建一个槽函数openSuccessSlot()连接,在槽函数中发送openSuccessSig()即可,由于槽函数在主线程中执行,所以最终openSuccessSig() 信号会在主线程中发送。
QCoreApplication::postEvent和QCoreApplication::sendEvent
postEvent: 可以给别的线程发送事件,事件会在目的对象所属的线程中运行。这是一个异步接口。sendEvent: 仅用于同一个线程之间发送事件,目的对象所属的线程必须与当前线程一样。这是一个同步接口。假如发送给属于另一个线程的对象,会报错:ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread.
QT中线程的使用还可以通过 .moveToThread() 函数改变一个线程的依附性;于是可以直接创建一个QThread 对象Thread,将一个QObeject对象obj.moveToThread(&Thread),当中,这样,可以使obj的槽函数在次线程中执行;而且此时次线程中仍然有事件循环,可以调用 Thread.quit() 停止事件循环,然后Thread.wait()函数等待结束。需要注意的是,子对象和父对象的线程依附性必须相同,否则会出错。
另外记录一点:用VS编译器,创建窗口对象时,必须的使用小写"com1" ,使用GCC编译器的QT,发现使用小写串口号无法打开串口号10以上,改为大写“COM10”可以解决。
- QT信号槽的跨线程连接
- Qt跨线程信号和槽的连接
- Qt跨线程信号和槽的连接
- QT跨线程连接信号和槽
- QT跨线程的信号与槽
- QT跨线程的信号与槽[2]---后台SOCKET
- QT 跨线程信号的注册
- QT 信号与槽在不同线程不能连接的问题
- QT 信号与槽在不同线程不能连接的问题
- QT 信号与槽在不同线程不能连接的问题
- QT信号与槽的自动连接
- 简单的Qt连接信号与槽
- 跨线程 信号的连接类型
- QT信号槽连接方式
- Qt 信号槽连接方式
- QT GUI(主)线程与子线程之间的通信——使用跨线程的信号槽
- Qt线程间的信号与槽 以及 QThread
- QT子线程与主线程的信号槽通信
- 师姐毕业后给大家的找工作经验
- PHP异常处理
- hdu2546 饭卡 (背包问题)
- 20150812Oracle学习笔记sqlplus常用命令与用户管理
- Uva821 Page Hopping(最短路径Floyd应用)
- QT信号槽的跨线程连接
- jquery easyui datagrid/table 右边线显示不全
- HTML5 Canvans 常用API整理
- OAF学习笔记-2-下拉框的制作
- 字符串常用方法
- Spring Hessian整合 404 问题
- POJ 2796
- IO多路复用之epoll总结
- OC循环渐进:文件管理--计算文件大小的五种方式