Qt事件循环 跨线程信号和槽
来源:互联网 发布:阿里云服务器做vpn 编辑:程序博客网 时间:2024/05/22 06:05
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){ pThreadCon = new CSerialThread(); pThreadCon->start(); m_pTimer = new QTimer(); connect(m_pTimer,SIGNAL(timeout()),SLOT(onTimer())); m_pTimer->start(1000);}void MainWindow::onTimer(){ m_pTimer->stop(); connect(this,SIGNAL(onSignal()),g_pThread,SLOT(onTimer()),Qt::QueuedConnection); emit onSignal(); this->disconnect();}void CSerialThread::run(){ g_pThread = new CThread();}CThread::CThread(QObject *parent) : QThread(parent){}void CThread::onTimer(){ sleep(5); qDebug("------onTimer call");}
只添加了部分代码,运行这个程序是看不到打印信息的,说明这个信号没有接收到,如果将connect最后一个参数改成直接连接,会有打印,但是主界面会卡住5秒。一直被这个问题困扰,为什么g_pThread 收不到信号呢,首先应该知道,Qt的信号和槽是基于事件循环的,就像main函数最后都会有一句return exec();这里就启动了事件循环,除了信号触发线程与接收者线程相同的情况能直接调用到slot,其它情况都依赖事件机制。QThread::run()实际上是简单调用了QThread::exec(),而它启动了线程的事件循环,但是run()函数结束后,事件循环结束了,这个时候我们再发送信号,没有事件循环的支持,g_pThread就收不到信号了。
QThread的内部结构非常有趣:
- QThread并不生存于执行run()的新线程内。它生存于旧线程中。
- QThread的大多数成员方法是线程的控制接口,并设计成从旧线程中被调用。不要使用moveToThread()将该接口移动到新创建的线程中;调用moveToThread(this)被视为不好的实践。
- exec()和静态方法usleep()、msleep()、sleep()要在新创建的线程中调用。
- QThread子类中定义的其他成员可在两个线程中访问。开发人员负责访问的控制。一个典型的策略是在start()被调用前设置成员变量。一旦工作线程开始运行,主线程不应该操作其他成员。当工作线程终止后,主线程可以再次访问其他成员。这是一个在线程开始前传递参数并在结束后收集结果的便捷的策略。
QObject必须始终和parent在同一个线程。
所以解决上面代码收不到信号的问题其实很简单,在线程的run();函数中添加一个事件循环就可以了,即加入一句exec();
有不对的地方希望大家指正,相互学习。
0 0
- Qt事件循环 跨线程信号和槽
- QT跨线程连接信号和槽
- QT 事件和信号
- Qt 事件和信号
- Qt跨线程信号和槽的连接
- Qt跨线程信号和槽的连接
- Qt线程与事件循环
- Qt 线程与事件循环
- QT事件循环与线程
- Qt:事件和事件循环
- Qt事件和事件循环
- 线程和事件循环
- 线程和事件循环
- QT信号槽的跨线程连接
- QT跨线程的信号与槽
- C++-Qt按钮事件(信号和槽机制)
- QT 线程间QThread的信号和槽
- Qt 的线程与事件循环
- 120001 Android视频录制
- Mac系统下配置Sublime Text的lua运行环境
- 避免变量重复定义和重复包含头文件的方法
- VS2010编译器经常遇到的小问题
- TCP/IP 工具收录
- Qt事件循环 跨线程信号和槽
- fragmentActivity跳转不成功
- An internal error occurred during: "Building workspace".
- POJ-2287-Tian Ji -- The Horse Racing
- iptables基础知识.详解
- 转:undefined reference to 'pthread_create'问题解决
- poj 1160 Post Office(DP-简单DP)
- Hibernate事务与并发问题处理(乐观锁与悲观锁)
- 轴承剥离型故障对应的特征频率