关于linux异步通知signal 和QT的信号槽
2016-03-05 22:04
399 查看
项目要进行ARM和DSP之间的通信,查了很多资料,最终决定用HPI,HPI驱动写完后,要写QT应用程序,方案是qt端给信号中断DSP,然后DSP处理完一帧数据后,中断ARM。
ARM接收到中断后调用read函数读一帧,然后显示,是设备主动中断应用程序通知读写的方式。
本人菜鸟一枚,花了好多时间从驱动的坑里跳出来后,转眼就跳入了QT的坑。so,问题在哪?驱动接收到中断后,怎样让应用层接收到信号,从而update()刷新UI。
查了些资料,发现了linux的异步通知,自己试着做了下,脱离qt的情况下完全没问题,应用程序反馈良好,然后加入到Qt程序里,利用异步通知调用的函数emit信号给主线程,在主线程的solt里update,自我感觉良好,实际开始写的时候问题就来了。
error: void (VideoDevice::)(int)’ does not match ‘void (*)(int)’ 谷歌了下,说是异步通知signal的处理函数必须使用c声明函数,类的不行,解决方案是把异步通知函数声明为静态成员函数。
声明称静态后,因为静态成员函数只能调用静态成员,于是把函数里用到的一堆成员都声明成静态,但是解决不掉的问题是,要发送给主线程的信号无法声明成静态的,原因是,QT的信号槽机制本身就是用于对象之间的通信,静态成员函数属于类,信号solt是通过moc转化的宏(不知道这样讲对不对),这个宏声明了信号要调用this指针。
所以信号声明成静态后就会出现 ‘this’ is unavailable for static member functions 这样的错误。
中间尝试过,某网友提供的解决方案,说是可能因为signal 重名的原因,于是换用宏Q_SIGNALS,Q_SLOTS,Q_EMIT。还要在pro中添加依据config += no_keyboard
试完后发现没什么用,应该用来是解决跟其他第三方库的信号槽重名问题的。
折腾了一天,还是没什么头绪,明天想试下,事件通知机制,不知道有没有用,先写到这,待更新。
更新:看了事件通知的一些相关内容,总感觉不是自己想要的方式。后来偶尔发现,其实解决问题的方式很简单都怪自己的基础不扎实,问题的原型是:静态函数成员调用非静态函数成员的方法。解决方案是这样的:在异步通知的应用程序的静态函数中,new一个device的指针,通过指针来调用对象的信号函数,于是就解决了C++函数回调机制里this指针的问题。也不知道这种方式是否正确,但是问题貌似解决了,至于有没有效,尚待验证,如果有高手看到此博客,希望能帮忙指正。
3.10更新:上次的方法测试的时候发现不行。原因是静态函数中new出的对象,作用域只在函数内,而信号槽机制绑定的信号槽都是对象的,所以没法绑定静态函数内new的对象,之前的方法绑定的对象是程序内调用静态函数的对象,所以不对。
解决方案是:
在类里添加一个指向本类的静态指针。
static VideoDevice * device;
然后提前初始化为new出的新对象。
VideoDevice* VideoDevice::device = new VideoDevice(tr("/dev/HPI"));
然后connect的时候绑定对象的静态成员,也就是这个静态指针。
connect(vd->device,SIGNAL(start_read()),this,SLOT(get_frame()));
这样就没问题了。
ARM接收到中断后调用read函数读一帧,然后显示,是设备主动中断应用程序通知读写的方式。
本人菜鸟一枚,花了好多时间从驱动的坑里跳出来后,转眼就跳入了QT的坑。so,问题在哪?驱动接收到中断后,怎样让应用层接收到信号,从而update()刷新UI。
查了些资料,发现了linux的异步通知,自己试着做了下,脱离qt的情况下完全没问题,应用程序反馈良好,然后加入到Qt程序里,利用异步通知调用的函数emit信号给主线程,在主线程的solt里update,自我感觉良好,实际开始写的时候问题就来了。
error: void (VideoDevice::)(int)’ does not match ‘void (*)(int)’ 谷歌了下,说是异步通知signal的处理函数必须使用c声明函数,类的不行,解决方案是把异步通知函数声明为静态成员函数。
声明称静态后,因为静态成员函数只能调用静态成员,于是把函数里用到的一堆成员都声明成静态,但是解决不掉的问题是,要发送给主线程的信号无法声明成静态的,原因是,QT的信号槽机制本身就是用于对象之间的通信,静态成员函数属于类,信号solt是通过moc转化的宏(不知道这样讲对不对),这个宏声明了信号要调用this指针。
所以信号声明成静态后就会出现 ‘this’ is unavailable for static member functions 这样的错误。
中间尝试过,某网友提供的解决方案,说是可能因为signal 重名的原因,于是换用宏Q_SIGNALS,Q_SLOTS,Q_EMIT。还要在pro中添加依据config += no_keyboard
试完后发现没什么用,应该用来是解决跟其他第三方库的信号槽重名问题的。
折腾了一天,还是没什么头绪,明天想试下,事件通知机制,不知道有没有用,先写到这,待更新。
更新:看了事件通知的一些相关内容,总感觉不是自己想要的方式。后来偶尔发现,其实解决问题的方式很简单都怪自己的基础不扎实,问题的原型是:静态函数成员调用非静态函数成员的方法。解决方案是这样的:在异步通知的应用程序的静态函数中,new一个device的指针,通过指针来调用对象的信号函数,于是就解决了C++函数回调机制里this指针的问题。也不知道这种方式是否正确,但是问题貌似解决了,至于有没有效,尚待验证,如果有高手看到此博客,希望能帮忙指正。
3.10更新:上次的方法测试的时候发现不行。原因是静态函数中new出的对象,作用域只在函数内,而信号槽机制绑定的信号槽都是对象的,所以没法绑定静态函数内new的对象,之前的方法绑定的对象是程序内调用静态函数的对象,所以不对。
解决方案是:
在类里添加一个指向本类的静态指针。
static VideoDevice * device;
然后提前初始化为new出的新对象。
VideoDevice* VideoDevice::device = new VideoDevice(tr("/dev/HPI"));
然后connect的时候绑定对象的静态成员,也就是这个静态指针。
connect(vd->device,SIGNAL(start_read()),this,SLOT(get_frame()));
这样就没问题了。
相关文章推荐
- Linux Mint 17.2 文本编辑器中文乱码问题
- Linux内核分析 实验二:完成一个简单的时间片轮转多道程序内核代码
- 【解决】在Linux系统下,使用cat查看含有中文的文本文件正常,但是使用vim打开却是乱码的解决方法
- Linux Mint 17.2 输入法安装
- Linux 下的 ~是什么意思
- linux下查找局域网内的ip
- WinXP下安装Linux Mint 17.2
- linux下vim的简单配置
- Linux的僵尸进程处理1
- Linux启动网卡时出现RTNETLINK answers: File exists错误解决方法
- CentOS查看系统信息命令和方法
- Introducing Linux Network Namespaces
- [国嵌攻略][107][Linux进程管理子系统]
- linux内核分析--操作系统是如何工作的?
- linux network namespace 学习
- Linux设备驱动第三版快速参考摘录
- Linux系统编程--文件IO操作
- linux小学生(一)之 linux简介
- Linux-find和grep命令
- Linux内核分析作业 NO.2