Sender
Sloter
Connection
那么Qt是怎么将这两个信号槽链接起来的呢?接下来看一看connect的源码:
在Qt中connect有很多个重载,大致可以分为2类:一种是qt4的Sender(),Slot()方式,另一种是qt5的模板方式进行链接
用这种方式链接会调用上图中的第一个connect函数,其内部的实现如下(太多了我们分段看看)
这一部分主要是在检测传入的信号是否属于sender,不是的话会告警并直接返回,这也是这种方式不好的地方,必须写正确,而且写错了如果不看告警的话是不知道的。
这里面两个主要的函数:
我们看看他们是如何实现的
通过Qt的元对象(QMetaObject)获取,到这里需要讲一讲QMetaObject是个什么东西,它是个类,内部有一个结构体d如下:
OK,继续回去看staticMetaObject这个成员的初始化,我们在这里先只关注stringdata和data这个两个参数,这里用到了,后面会继续有其他参数的意义,在这个地方stringdata被初始化成了qt_meta_stringdata_TestSenderdata,data被初始化成了qt_meta_data_TestSender。它们是啥,还是在moc文件里
这两个一个保存着信号的名字,一个保存着信号的返回值,参数类型和参数个数。
到这里就可以通过这两个参数和链接时传入的signal字符串对比找到信号在sender中的的位置,当然因为继承的存在,所以这个位置不是真是的位置,还需要找到signalOffset这个函数找到在这个类中的位置。怎么找的呢?其实MetaObject中的data最终会被转换成这个
因为QObject有2个信号,所有这个地方获取到的索引位置为3
这一段跟上面差不多,用来检车receiver和槽函数是否对应
这个地方主要是检查信号槽的参数(比如信号的参数不能比槽的参数少等)
接下来就会进入另一个connect函数,他的实现
到这里就要看到信号槽是如何链接起来的了,每个QObject的对象都会维护着多个Connection的链接对象,这里面存储着信号的发送者、信号的接收者等一系列信息
至此信号差就链接起来了,最终会以Connection对象的方式存放在每个QObject对象的connectionlist里面,这种是Qt4老的链接方式
Qt5的新链接方式相比Qt4要简单很多,因为是基于模板实现的,因此可以直接找到函数的地址,最终也会放到链接列表里,来看看与Qt4的区别吧。
不知道是否还记得最开始connect函数的几种重载,这里用到的是下面红框里的方式(模板)
让我们先看一种
它会调用这个实例化的模板函数
看到了吧,这个函数有2个功能,一个是执行信号(因为信号可能会很信号链接,具体怎么执行到的后面会讲),另一个是获取信号函数在对象的偏移量(如何获取的呢,其实就是对比传入的信号函数的地址和实际信号的地址,这里a0就是要获取的偏移量,a1就是信号函数的地址)
这个地方需要注意的是connecImpl与connect不同的是吧receiver对象包装成了一个QSlotObject的对象,它是这样的
这个类接受一个QtPrivate::FunctionPointer<Func>的对象,这个是个啥?着其实是个模板类,用来识别槽函数的地址,在connect的时候也用到了这个,具体怎么实现的可以放出来,就是模板的推导比较麻烦,可以简单的理解成通过这个可以判断槽函数是否是receiver的成员函数
接着往下讲,不知道是否还记得之前的connectImpl函数,它获取到了信号的偏移量,接着又调用了一个connectImpl,它是这样的
看到这里有没有熟悉的感觉,跟Qt4的其实差不多,也是将信号槽存储到connection对象内,在添加到sender的connectionList里,不过这里存储的槽不是一个函数,而是一个QSlotObject对象的地址,看看Connection结构的内容可以发现使用Union实现的,存储的都是一个地址
到这里就讲完了Qt4和Qt5信号槽的链接部分,不知道是否讲的明白,moc文件里生成的东西基本就是Qt信号槽的核心,每一个都有其作用,都对应着QObjcet底层的数据,也是Qt元对象的核心。
if (ClipboardGetDataObject() != null)//判断剪贴板上面有没有东西,有则继续下面的语句
{
if (ClipboardContainsFileDropList())
{
foreach ( String s in ClipboardGetFileDropList())
{
MessageBoxShow("内容或路径:"+s);
}
}
IDataObject data = ClipboardGetDataObject();//从剪贴板中获取数据
if (dataGetDataPresent(typeof(Bitmap)))//判断是否是类型
{
Bitmap map = (Bitmap)dataGetData(typeof(Bitmap));//将数据存到位图中
//thispictureBox1Image = map;//显示
mapSave(@"C:\liuleiqtbmp");//保存
}
if (dataGetDataPresent(DataFormatsText))//是否是文字
MessageBoxShow((dataGetData(DataFormatsText))ToString());
}
1、Linux下Qt Creator的配置
从Dash中找到Qt
Creator,打开,打开后可以看到主界面,这个界面和Windows下基本一致(后面安装windows版本就清楚了),在前面的两篇文章中我已经分
别编译了Linux下的X86平台和ARM平台的QT库,这部分就针对这个IDE进行相应的配置,是能够进行应用程序的开发。
在主界面中从菜单栏点击"工具"->"选项"->在左侧点击“构建和运行”界面如下图所示。
从
图中可以看到,IDE并没有自动识别安装的QT,这是因为在缺乏系统环境变量的情况下,不知道程序安装到了什么地方,所以这里需要手动设置,手动设置很简
单,只需要点击添加,分别添加编译的两个版本的QT安装文件中的qmake文件即可,注意是安装文件,并不是之前解压的源文件。
默认的安装路径为/usr/local/Trolltech这个文件夹下有两个文件夹,具体路径可以参见上图。
到这里就告诉IDE 安装QT的位置了,由于需要进行编译开发,接下来还需要指定编译器,点击“编译器”选项卡,如下图所示。
如图中所示,Qt Creator已经检测到X86的GCC,而我们要是做arm平台开发的话还需要指定用于arm开发的交叉工具链,我的安装路径为/usr/local/arm/432/bin/需要指定g++文件,如图中所示。配置完成后,点击“应用”。
QT和编译器指定完成后就需要进行下一步配置了,就是对这些工具进行组合,点击“构建套件(kit)”选项卡,如下图所示。
如上图所示,这里所做的设置也很简单,相当于是设定几种方案,指定设备类型、所用的编译器版本以及QT版本,我这里配置桌面和ARM两项,分别对应在PC和开发板两个平台。
到这里,基本配置就完成了。
2、使用Qt Creator进行初步开发
下面新建一个项目,点击菜单 ”文件“->”新建“,如下图所示,选择应用程序-Qt Gui应用
接
下来填写项目名称和选择保存位置,点击”下一步“选择构建套件,这里用于选择使用的构建套件,即上文配置的,按照上文配置我这里就有两个套件,桌面和
ARM,这个地方后面是可以更改的,因此我这里还是先选择桌面,下面有对应的Debug与Release这里保持默认。接下来全部保持默认一直到完成。
工程新建完成后就可以看到工程目录即文件了,如下图所示。
第
一个例程就不添加啥程序了,充分利用IDE设计的方便之处,拖拽几个控件运行示意一下吧,双击上图中的界面文件下的mianwindowui文件,接下
来就能看到和VS下利用C#等开发非常类似的界面,可以从左侧选择一些控件,右下角可以针对具体的控件属性进行修改,如下图所示,拖出自己需要的控件,并
进行简单修改。
我这里拖了几个作为示意,这部分弄好后,点击左下角的
直接运行,构建完成后就会d出刚刚设计的界面,如下图所示。
可
以看到实际运行效果和编辑的情况由于字体等因素略有差异。接下来就要生成一个能够在开发板上运行的程序了,由于刚刚在新建项目的时候构建套件选择的是桌
面,所以首先要对这点进行更改。如下图所示,点击
”项目“--”添加构建套件“下方就会d出我刚刚设定的ARM,在arm的构建设置中可以使用默认配置,其他相关选项可以参考桌面选项更改。
需
要说明的是在ARM的运行项目中,需要部署到远程运行,这里没有部署,因此在剪辑编辑进行构建的时候,就不能改直接运行了,点击锤子图标,进行构建,构建
完成后可以在工程文件夹下,如下图所示,那么在ARM开发板上运行的程序就在test1-build-ARM-_____Debug文件夹下。
接下来把生成的可执行文件拷贝到开发板进行运行,我这里使用的是nfs挂载的方式,通过超级终端运行
/test1 –qws
运行程序,需要说明的是我使用的开发板是飞凌的OK6410,上面已经移植好了QTE 473,虽然我的版本是484但是运行没有问题,其他平台需要先移植QT,这个暂时不在本文的讨论范围之内,运行效果如下:
到这里,用于开发板运行的第一个小程序就跑起来了。
3、Windows下Qt的安装
Linux下的安装和配置搞定了,Windows下的就非常简单了,Windows下有针对VS2008/2010以及Mingw的版本,虽然我电脑里装了VS2010,这里还是决定安装Mingw的版本,首先下载相关文件,下载地址:
>
首先vs要安装QT 插件。QT VS Tools
然后右键工程目录里面需要建立UI文件的文件夹,添加-》新建项,选择QT,出现QT UI模板,选择需要的。
然后加入对应的xxh 和xxcpp
DlgRoomsh
DlgRoomscpp
之后还要添加到CMakeListtxt
OK 了。 UI文件在QT设计师中编辑。然后绑定信号,槽神马的就可以了。
用户可在QT语音创建属于自己的房间,在主窗口左上角类似的图标“创建房间按钮”按要求填入指定资料即可申请到一个7位号码的房间,请注意创建房间成功后的回收规则。目前每个用户最多可以创建3个房间,创建成功后不能删除和转让。
选择你喜欢的房间号,还可以进行手动搜号搜索出你喜欢的房间号。
然后点击。房间创建成功。
子房间创建方法:
在成员列表中选择某个房间后,在鼠标右键菜单中选择创建子级房间或创建同级房间
或者可以通过点击主房间菜单,选择创建子级房间在创建子房间面板中输入房间名称,点击创建按钮可创建一个子房间勾选需要密码,则管理以下人员进入该子房间需要密码确认才可进入
以上就是关于Qt信号槽原理(链接)全部的内容,包括:Qt信号槽原理(链接)、C#复制一个图片 如何获得该图片路径、qt creator 自动检测 没有等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)