1、QT跨平台的实现机制
跨平台:
狭隘的理解:一个程序能在不同的平台上跑,操作系统就是平台。
广义的理解:平台就是API的提供者,API你就可以理解为系统提供给你的函数,就是不需要你自己写的,系统自带的,并且只有这个系统才有的。提供API的不一定是操作系统,也可能是软件,虚拟机或者其他的什么。
实现机制:
和java一样,针对每一种OS平台,QT都有一套对应的底层类库,而接口是完全一致的。
因此只要是在QT库上开发的程序,放在任何一种平台下都可以编译运行(前提条件是:程序中没有使用某OS特有的机能)。
也就是说在OS和应用层之间,增加了一个平台层来保证可移植性。
2、对Qt编译环境的认识
简单地讲,Qt其实就是一个C++的类库。配置编译环境,其实就是配置一个C++编译环境,同时将Qt库载入进来。当然Qt还额外提供了自己内部的一些功能,例如界面编辑器(designer)等。网上有很多配置开发环境的文章,多是手把手一步一步讲,非常详细。但是我初学的时候仍会出一些问题,不知道怎么解决。这里对整个编译环境做一个介绍,希望对大家有帮助,在出问题的时候知道从何下手。
编译器与Qt库
Qt是跨平台的库,不论你在哪个平台下使用,都需要一个编译器。windows下如果使用VS2010、VS2012等做编译器,则需要到Qt官网下载对应编译器版本的Qt二进制库文件。换句话说,如果安装了在VS2010版本的Qt二进制库文件,则必须安装VS2010做编译器Qt程序才能编译。如大家所知道的,不同的编译器编译同一段代码生成的库是不能替代使用的,也就是说用VS2008编译出来的Qt库,不能在VS2010做编译器时使用。对于大部分平台的编译器在官网上都能下载(例如windows、linux、android、ios、mac),但在嵌入式Linux平台(也就是我们做毕设需要用的Arm上的Qt程序)Qt没有提供二进制库文件,所以我们首先需要一个交叉编译器(arm-linux-gcc),然后下载Qt的源代码,使用这个针对arm的编译器编译Qt的源代码生成我们需要的Qt库。
调试器
有了编译器与对应的Qt库我们就可以编译发布版本的Qt应用程序了,但是不能调试。如果点击debug按钮,可能会提示未发现可用的调试器。所以我们还需要一个调试器,windows下VS做编译器的时候需要CDB来做调试器,MinGw做编译器需要gdb来做编译器。如果你的编译器出了问题,下载并安装你需要的调试器,然后也是在 工具(Tools)-->选项(Option)-->构建和运行(Build and run)中进行配置。
构建套件(Kit)
有了编译器、Qt库、调试器三个东西,我们就可以编译Qt应用程序了,但是我们的电脑上可能有多个版本的Qt库与编译器,我的电脑上就装了MinGw版的Qt5.3和VS2010版的Qt4.8。那么我们编译的时候使用那个版本来进行编译呢。这就要用到构建套件来进行管理。我们可以在工具(Tools)-->选项(Option)-->构建和运行(Build and run)中新建一个构建套件,取名叫“Desktop Qt 5.3 MinGW 32bit”然后分别为他们配置Mingw作为编译器,Qt5.3库(Mingw版的),编译器gdb。也可以再添加其他的构建套件,例如 Windows。
我们就可以使用这个构建来进行编译、调试程序。
3、QT跟MFC的区别v
QT是跨平台的开发工具
MFC其实是封装了winAPI,里面既有面向对象,也有面向流程的,比较乱,更没有逻辑,入门比较不容易。使用vc++编译器
QT更面向对象,引入信号与槽的机制,是编程看起来更有逻辑,入门比较容易。QT使用gcc编译器(MinGW)
QT由于封装得层数比较多,所以运行的时候效率会比MFC低一些。(MFC>QT>C#)
4、信号与槽机制
实现机制:
QT中信号与槽的机制依靠元数据来实现,
调用方式:
signal/slot目前有三种调用方式
1.DirectConnection
和以前一样,在emit处直接invoke你的slot 函数,一般情况是sender,receiver在同一线程
2.QueuedConnection
将发送Event给你的receiver所在的线程
postEvent(QEvent::MetaCall,...)
slot 函数会在receiver所在的线程的event loop中进行处理,一般情况是sender,receiver不在同一线程
3.BlockingQueuedConnection
调用sendEvent(QEvent::MetaCall,...),在receiver所在的线程处理完成后才会返回;只能当sender,receiver不在同一线程时才可以
信号与槽关系:
一个信号可以连接多个槽,一个槽可以连接多个信号
一个信号可以跟一个信号相连接
连接可以被移除(disconnect())