Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总
来源:互联网 发布:2017网络效应判断题 编辑:程序博客网 时间:2024/05/21 06:42
一、目录
转载1: http://my.oschina.net/fanhuazi/blog/737224?ref=myread 点击打开链接
转载2: http://www.qtcn.org/bbs/read-htm-tid-60505-ds-1-page-1.html#172183 点击打开链接
二、内容
由于以下两篇转载文章都使用了C++11 新特性“lamda表达式”,为了方便同仁阅读以下内容,在此引用一片文章对“C++11 lamda表达式”做一个简要介绍:
“C++11 lamda表达式” ,点击此链接先了解C++11新增语法,对后面内容的阅读会有帮助。
转载1: http://my.oschina.net/fanhuazi/blog/737224?ref=myread 点击打开链接
在Qt中将函数发送到主线程执行
……(省略部分内容,完成内容请参看上面的原文链接)数据共享的问题,试想“后台线程(非UI线程)中的数据如何能够被前台(UI线程)所使用,而且前台后台不一定在一个类里面?把数据打包通过信号传给前台?”想想就是很麻烦的事情,难道每个这样的需求场合都要做一遍这样的事情吗?感谢时间,因为时间穿过2011年,C++的新标准已经完美的解决了这个问题,那就是函数对象。
Qt的4.8.6版本所使用的mingw4.9.2版本是支持C++11的,如果你用的是老掉牙的rhel5系统,则需要升级编译器了,因为C++11要在GCC 4.5以上的版本中才会支持。
首先我们定义一个类:FunctionTransfer(函数大挪移),这个类继承自QObject,并使用Q_OBJECT标签来使用信号槽机制。代码中的“std::tr1::function<void()>”就是C++标准库中大名鼎鼎的函数对象。
class FunctionTransfer : public QObject{ Q_OBJECTpublic: ///@brief 构造函数 explicit FunctionTransfer(QObject *parent = 0);public: ///@brief 制定函数f在main中执行static void execinmain(std::tr1::function<void()> f);signals: ///@brief 在别的线程有函数对象传来 void comming(std::tr1::function<void()> f);public slots: ///@brief 执行函数对象 void exec(std::tr1::function<void()> f);};
//在全局数据区实例化一个FunctionTransfer的实例,该实例所在的县城就是主线程。FunctionTransfer main_thread_forward;void FunctionTransfer::execinmain(std::tr1::function<void()> f){ main_thread_forward.exec(f);} FunctionTransfer::FunctionTransfer(QObject *parent) : QObject(parent){ connect(this,SIGNAL(comming(std::tr1::function<void()>)),this,SLOT(exec(std::tr1::function<void()>)),Qt::BlockingQueuedConnection);} void FunctionTransfer::exec(std::tr1::function<void()> f){ if(Gt::isMainThread()) { f(); } else { emit this->comming(f); }}
非常简单的逻辑,如果在主线程就执行,如果不是在主线程就发给主线程,主线程接到之后就执行。
类有了,接下来考虑实用的场合,比如有一个类 A,A有个方法f不能再后台执行,需要跑到前台,怎么办呢,上代码:
FunctionTransfer::execinmain([this](){this->f();});作为参数的lamda表达式捕获了类A的this指针,然后转换为C++的函数对象,然后跑到前台去执行了,执行完成后才会返回,是不是灰常简洁。
转载2:http://www.qtcn.org/bbs/read-htm-tid-60505-ds-1-page-1.html#172183 点击打开链接
#pragma once#include <qthread.h>#include <functional>class QIoService : QObject{public: QIoService(bool startinthread) { if(startinthread) { worker=new QThread(NULL); worker->start(); this->moveToThread(worker); } else { //this object is created in create thread!!! } } void post(std::function<void()> func); void send(std::function<void()> func); void post(std::function<void()> func,int ms); void send(std::function<void()> func,int ms); virtual bool event ( QEvent * e); protected: QThread *worker;};//this should run in mainthreadextern QIoService *main_ioservice;#include "stdafx.h"#include "qioservice.h"#include <qapplication.h>#include <qtconcurrentrun.h>QIoService *main_ioservice=NULL;class FunctionEvent : public QEvent{public: static const QEvent::Type myType = static_cast<QEvent::Type>(2000); FunctionEvent(std::function<void()> f) :QEvent(myType) { func=f; } ~FunctionEvent() { //这个他会自动删除 } std::function<void()> func; };void QIoService::post(std::function<void()> func){ QApplication::instance()->postEvent(this,new FunctionEvent(func));}void QIoService::send(std::function<void()> func){ QApplication::instance()->sendEvent(this,new FunctionEvent(func));}void QIoService::post(std::function<void()> func,int ms){ auto lam = [&]() { QThread::currentThread()->wait(ms); post(func); }; QtConcurrent::run(lam);}void QIoService::send(std::function<void()> func,int ms){ auto lam = [&]() { QThread::currentThread()->wait(ms); send(func); }; QtConcurrent::run(lam); }bool QIoService::event ( QEvent * e){ if(e->type()==FunctionEvent::myType) { FunctionEvent *fe=(FunctionEvent *)e; fe->func(); return true; //这个他会自动删除,不用我们自己手工delete } return false;}注解:
//比如你在另外一个线程,你收到数据,想修改界面。就弄个全局变量QIoService g_ui_ios(false);
//你只要g_ui_ios.send([你的变量]{ //修改界面数据,这个会在主线程执行});//如果你是想写个任务队列,QIoService g_worker_ios(true);
//你要把某段事情丢到其他线程执行,就g_worker_ios.send([]{ //这段会在其他线程执行。 如果执行完了,又想在主线程执行某段,这里可以继续 //g_ui_ios.send([] { //这段会在主线程执行 });});
三、更新
2016年8月27日 第一次更新
- Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总
- Qt跨线程信号和槽的连接
- Qt跨线程信号和槽的连接
- QT跨线程连接信号和槽
- QT信号槽的跨线程连接
- QT跨线程的信号与槽
- Qt信号和槽的实现揭秘
- Qt信号和槽的实现揭秘
- QT 线程间QThread的信号和槽
- QT 跨线程发送信号非元数据信号解决
- QT子线程发射信号,UI接收信号刷新UI
- Qt事件循环 跨线程信号和槽
- Qt 信号槽的实现
- QT的信号和信号槽
- qt GUI线程和其他线程的信号槽以及不同线程通信
- QT跨线程的信号与槽[2]---后台SOCKET
- QT 跨线程信号的注册
- QT的信号和槽
- java身份证识别
- Android基础类之BaseAdapter
- android 出现 cannot resolve symbol r
- swift实现微信通讯录列表TableView的创建
- HDU 3530 Subsequence
- Qt 跨UI线程的数据交换和信号-槽调用实现方案汇总
- 【iOS-报错】:“App Transport Security has blocked a cleartext HTTP”
- python 关于获取某一目录下的所有文件名并保存至txt文件
- ruby 中super和super()的区别
- Razor引擎学习:RenderBody,RenderPage和RenderSection
- 使用ListAcyivity实现动态菜单列表
- 【NOI OJ】1455 An Easy Problem(简单模拟题)
- 欢迎使用CSDN-markdown编辑器
- CRF++中文分词