题目:嵌入式系统下的Qt开发
学生姓名:
专 业:计算机科学与技术 班 级: 指导教师:
2012年12 月 7 日
摘要………………………………………………………………………………………………. 2 Linux和Qt简介............................................................................... 3 Linux主要特性 ................................................................................ 3 Qt开发工具简介 .............................................................................. 4
Qt主要特性........................................................................ 4 Qt编程机制........................................................................ 4
Qt/Embedded开发环境的建立........................................................... 6 应用程序的开发一个小的Qt实例-简单计算 ......................................... 8
界面设计............................................................................ 9 具体界面设计效果如下 ........................................................ 9 辅助数据成员及函数........................................................... 10 calculat.cpp中辅助函数的实现 ............................................ 11 main.cpp文件 ................................................................... 12
结束语........................................................................................... 13 附录 .............................................................................................. 13
1
摘要
越来越多的嵌入式终端需要一个图形化的人机接口界面(GUI),良好的人机交互界面是嵌入式系统设计的一个关键技术,尤其是在嵌入式手持设备中,对嵌入式终端的实用性、美观性和视听娱乐性提出了更高的要求。而基于嵌入式Qt编程界面美观、功能丰富、交互性好,具有一定的实用意义和价值。本文通过实例,介绍了Linux的优点和Qt开发环境的搭建,分析了Qt在软件开发中的编程机制,并简单介绍Qt/Embedded图形系统的移植。
关键词:Qt ,Linux,嵌入式,图形界面,计算器
2
Linux和Qt简介
Linux主要特性
Linux是个和Unix相似、以Unix核心为基础、完全内存保护、多任务多进程的操作系统。支持广发的计算机硬件,包括X86,Alpha,Sparc,MIPS,PPC,ARM,NEC等现有的大部分芯片。程式源码全部公开,任何人可以修改并在GNU通用公共许可证(GNU General Public License)下发行(陈英和梁建武,2008),这样,开发人员可以对操作系统进行定制,再也不必担心像MS windows操作系统中\"后门\"的威胁。同时由于有GPL的控制,大家开发的东西大都相互兼容,不会走向分裂之路。Linux用户遇到问题时可以通过Internet向网上成千上万的Linux开发者请教,这使最困难的问题也有办法解决。Linux带有Unix用户熟悉的完善的开发工具,几乎所有的Unix系统的应用软件都已移植到了Linux上。Linux还提供了强大的网络功能,有多种可选择窗口管理器(X windows)。其强大的语言编译器gcc、g++等也可以很容易得到。不但成熟完善、而且使用方便,为嵌入操作系统提供了一个极有吸引力的选择。
Linux已经被移植到多种硬件平台,这对受开销、时间限制的研究与开发项目是很有吸引力的。原型可以在标准平台上开发然后移植到具体的硬件上,加快了软件与硬件的开发过程。
Linux还有以下优点:
(1) Linux可以随意地配置,不需要任何的许可证或商家的合作关系。 (2) 它是免费的,源代码可以得到。这是最吸引人的。毫无疑问,这会节省大量的开发费用。
(3) 它本身内置网络支持。
(4) Linux的高度模块化使添加部件非常容易。
(5) Linux在台式机上的成功,使大家看到了linux在嵌入式系统中的辉煌前景。
嵌入式产品中选择什么样的操作系统极为重要,嵌入式Linux由于其开源特性、实时性好、可移植、内置网络支持等优点在嵌入式领域成为主力军。如今,业界已经达成共识:即嵌入式linux是大势所趋,其巨大的市场潜力与酝酿的无限商机必然会吸引众多的厂商进入这一领域。
3
Qt开发工具简介
Qt主要特性
QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象、易于扩展、真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT 库的基础之上。QT 支持下列平台:MS/WINDOWS-95、98、NT 和 2000;UNIX/X11-Linux、Sun Solaris、HP-UX、Digital Unix、IBM AIX、SGI IRIX;EMBEDDED- 支持 framebuffer 的 Linux 平台。伴随着 KDE 的快速发展和普及,QT 很可能成为 Linux 窗口平台上进行软件开发时的 GUI 首选。
Qt编程机制
信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言,因此要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler)的 QT 工具,该工具是一个 C++ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。
在我们所熟知的很多 GUI 工具包中,窗口小部件 (widget) 都有一个回调函数用于响应它们能触发的每个动作,这个回调函数通常是一个指向某个函数的指针。但是,在 QT 中信号和槽取代了这些凌乱的函数指针,使得我们编写这些通信程序更为简洁明了。 信号和槽能携带任意数量和任意类型的参数,他们是类型完全安全的,不会像回调函数那样产生 core dumps。
所有从 QObject 或其子类 ( 例如 Qwidget) 派生的类都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射 (emit) 出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且,对象并不了解具体的通信机制。
你可以将很多信号与单个的槽进行连接,也可以将单个的信号与很多的槽进行连接,甚至于将一个信号与另外一个信号相连接也是可能的,这时无论第一个信号什么时候发射系统都将立刻发射第二个信号。总之,信号与槽构造了
4
一个强大的部件编程机制。
信号和槽的连接原理图
信号:当某个信号对其客户或所有者发生的内部状态发生改变,信号被一个
对象发射。只有 定义过这个信号的类及其派生类能够发射这个信号。当一个信号被发射时,与其相关联的槽将被立刻执行,就象一个正常的函数调用一样。信号 - 槽机制完全独立于任何 GUI 事件循环。只有当所有的槽返回以后发射函数(emit)才返回。 如果存在多个槽与某个信号相关联,那么,当这个信号被发射时,这些槽将会一个接一个地 执行,但是它们执行的顺序将会是随机的、不确定的,我们不能人为地指定哪个先执行、哪 个后执行。
信号的声明是在头文件中进行的,QT 的 signals 关键字指出进入了信号声明区,随后即可 声明自己的信号。例如,下面定义了三个信号:
signals: void mySignal();
void mySignal(int x);
void mySignalParam(int x,int y);
在上面的定义中,signals 是 QT 的关键字,而非 C/C++ 的。接下来的一行 void mySignal() 定义了信号 mySignal,这个信号没有携带参数;接下来的一行 void mySignal(int x) 定义 了重名信号 mySignal,但是它携带一个整形参数,这有点类似于 C++ 中的虚函数。从形式上 讲信号的声明与普通的 C++ 函数是一样的,但是信号却没有函数体定义,另外,信号的返回 类型都是 void,不要指望能从信号返回什么有用信息。
5
信号由 moc 自动产生,它们不应该在 .cpp 文件中实现。
槽:槽是普通的 C++ 成员函数,可以被正常调用,它们唯一的特殊性就是很
多信号可以与其相关联。当与其关联的信号被发射时,这个槽就会被调用。槽可以有参数,但槽的参数不能有缺省值。
既然槽是普通的成员函数,因此与其它的函数一样,它们也有存取权限。槽的存取权限决定了谁能够与其相关联。同普通的 C++ 成员函数一样,槽函数也分为三种类型,即 public slots、private slots 和 protected slots。
public slots:在这个区内声明的槽意味着任何对象都可将信号与之相连接。这对于组件编程非常有用,你可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。
protected slots:在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。这适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。
private slots:在这个区内声明的槽意味着只有类自己可以将信号与之相连接。这适用于联系非常紧密的类。
槽也能够声明为虚函数,这也是非常有用的。
槽的声明也是在头文件中进行的。例如,下面声明了三个槽: public slots: void mySlot(); void mySlot(int x); void mySignalParam(int x,int y);
Qt/Embedded开发环境的建立
Qt是一个全面的C++应用程序开发框架。它包含一个类库,和用于跨平台开发及国际化的工具。由挪威Trolltech公司推出,主要通过汇集C++类的形式来实现提供开发应用程序用户界面部分的需求。Qt/Embedded是一个为嵌入式设备上的图形用户接口和应用程序开发而定做的C++工具开发包。是一组用于访问嵌入式设备的QtC++API。它可以运行在多种不同的处理器上部署的嵌入式Linux操作系统上。Qtopia是Trolltech公司为采用Linux操作系统的消费电
6
子设备而开发的综合应用平台。Qtopia包括完整的应用层、灵活的用户界面、窗口操作系统、应用程序启动程序以及开发框架。
准备以下源码包和文件
1tmake211111tar1gz(用于生成Makefile文件辅助工具) ○
②qt2embedded2213171tar1gz(Qtopia建立的基础)
③qt2x112213121tar1gz(用于生成moc和uic两个工具) ④qtopia2free2117101tar1bz2(Qtopia源代码包) ⑤cross2313121tar1bz2(交叉编译器) 开发环境建立过程
新建一个目录:/usr/local/arm/QT,并将上面的5个源码包放到/usr/localarm/QT?目录下
① tmake的安装
#tarzxvftmake-1.11tar.gz #cdtmake-1.11
建立shell文件,在文件中添加如下内容,操作为打开端。输入: #vienv.sh
exportTMAKED IR=$PWD
exportTMA KEPA TH=$TMAKED IR/lib/qws/linux-arm-g++ exportPATH=$TMAKEDIR/bin:$PATH 保存退出。并添加环境变量如下 #sourceenv.sh ②QtX11的安装
#tar-vxzfqt-x11-2.3.2.tar.gz #cdqt-2.3.2
#vienv.sh(操作同上上制env1sh文件方法)
exportQTDIR=$PWDexportPATH=$QTDIR/bin:$PATH exportLDLIBRARYPATH=$QTDIR/lib:$LDLIBRARYPATH 保存退出。并添加环境变量 #sourceenv.sh
生成Makefile后,就可以进行安装 #make
安装成功后,将会有以下打印信息: Enjoy!-theTrolltechteam 编译生成qvfb、qembed工具 #make-Ctools/qvfb #make-Ctools/qembed ③Qt/Embedded安装 #cdusr/local/arm #mkdir3.3.2
#tarzxvfcross-3.3.2.tar.bz2 #cdusr/local/arm/QT
#tarzxvfqt-embedded-2.3.7.tar.gz
7
进入软件包中并设置一些环境变量: #cdqt-2.3.7
#exportPATH=/usr/local/arm/3.3.2.bin:$PATH #exportQTDIR=$PWD #exportQTEDIR=$QTDIR
在qconfiglocal.h文件中添加一行: #defineQT_QWS_IPAQ_RAW
添加完之后将该文件拷贝到src/tools/目录 #cp/qconfig2local1hsrc/tools
将qt-2.3.2源码编译后的uic工具拷贝到bin目录 #cp qt-2.3.2/bin/uic1/bin 交叉编译,设置编译选项:
#./configure-xplatformlinux-arm-g++-shared-qconfiglocal-qvfb-depths4,8,16,32-gif-system-jpeg
生成Makefile之后,就可以进行编译了: #make
④qtopia的安装
#tarzxvfqtopia-free-1.7.0.tar.gz 设置环境变量:
#exportQTDIR=$QTEDIR#exportQPEDIR=$PW #exportPATH=$QPEDIRbin/:$PATH
接下来就可以配置了:
#cdsrc/#1/configure-platformlinux-arm-g++ 生成Makefile之后,就可以进行编译了: #make
以上过程编译通过后,Qt/Embedded开发环境已经建立,并且Qt/Embedded和Qtopia面向目标机的交叉编译环境也构建完成,设置环境变量set-env,就可以使用Qt来进行应用程序开发了
应用程序的开发一个小的Qt实例-简单计算
8
界面设计
界面设计我们是使用Qt creator进行设计的,首先创建一
QMainWindow.ui,这个界面为QWidget。然后在左侧的Widget Box找相应的控件添加到QMainWindow里。首先提出一个lineEdit控件作为算式显示窗口和结果显示窗口,在提取出30个QpushButton为0到9按键和加减乘除按键,小数点按键、等于按键。然后再把各个pushButton名字改成相应的符号,并且改对应pushbutton的属性,保存后取Qt creator编译QMainWindow.ui,运行程序就可以显示相应界面。
具体界面设计效果如下
为符合人们的使用习惯,将lineEdit空间的属性更改,使得输入的数字和符号出现在空间的右边起。如图:
对于button exit退出程序,这样简单的响应,直接在设计器中通过添加信号和槽来完成,如图:
9
辅助数据成员及函数
为了区分每一次计算和保存操作数、操作符,和辅助函数(如:输出函数),在calculator.h的类中设定数据成员以及成员函数: private slots:
void on_but_0_clicked(); void on_but_1_clicked(); void on_but_2_clicked(); void on_but_3_clicked(); void on_but_4_clicked(); void on_but_5_clicked(); void on_but_6_clicked(); void on_but_7_clicked(); void on_but_8_clicked(); void on_but_9_clicked(); void on_butadd_clicked(); void on_butsub_clicked(); void on_butmul_clicked(); void on_butdiv_clicked(); void on_buteq_clicked(); void on_bbut_clicked(); void on_abut_clicked(); void on_butp_clicked(); void on_butcls_clicked();
private:
Ui::calculatorClass ui;
bool finishedOne;//是否完成了一趟计算 bool haveDian;//是否已经输入了点
10
bool haveOpera;//是否已经输入过操作符 bool newInput;//清屏后的标志 double num1;//操作数 double num2;//操作数 char opera;//运算符
QString str;//用来进行double和string之间转换
void clear_lineEdit();//每输入一个操作数或操作符的小清屏 void input(char ch);//向lineEdit进行输入 void inputCheck();//输入前的检查
calculat.cpp中辅助函数的实现
void calculator::input(char ch) //输入函数 {
if (newInput) //如果是新开始的输入,则先清空 {
ui.lineEdit->clear(); }
ui.lineEdit->setText(ui.lineEdit->text()+ch); //lineEdit内容等于原有的加上输入的字符
newInput = false; }
void calculator::inputCheck()//输入前判断是否是新的一次计算,并更新数据 {
if (finishedOne)
{//标志新的一轮计算,和小数点,操作符,新输入的标志量重置 finishedOne = false;
11
haveDian = false; haveOpera = false; newInput = true;
//并清空lineEdit clear_lineEdit(); } }
//小清零,为的是在输入完操作数后,要输入操作符的时候,要清屏 void calculator::clear_lineEdit() {
ui.lineEdit->clear(); haveDian = false; newInput = true;
ui.butDian->setEnabled(true);//小数点按钮可用 }
main.cpp文件
#include \"calculator.h\" #include int main(int argc, char *argv[]) { QApplication a(argc, argv); calculator w; w.show(); return a.exec(); } 12 结束语 目前,嵌入式系统是近年来发展很快的计算机方面的学科方向,并迅速渗透到控制、自动化、仪器仪表等学科。随着嵌入式处理器运算能力的不断提高以及对外设支持的不断丰富,嵌入式Linux系统的应用逐渐增多。嵌入式终端需要一个图形化的人机接口界面,良好的人机交互界面是嵌入式系统设计的一个关键技术,尤其是在嵌入式手持设备中,对嵌入式终端的实用性、美观性、视听娱乐性以及人机交互方面提出了更高的要求。而Qt/Embedded延续了Qt在桌面系统的所有功能,丰富API接口和给予组件的编程模型使得嵌入式Linux系统中的应用程序开发更加方便。由于Qt/Embedded本身面向高端的手持式设备和移动设备,将成为未来嵌入式系统的主流。这些应用的关键在于人机交换技术的体现,所以一个十分友好的图形用户界面(GUI)是必不可少的。本文简单介绍了Qt/Embedded开发环境的建立过程和基于Qt开发应用程序的方法。希望对他人具有一定的实用意义和价值 附录 参考文献:[1]赵宏 王小牛 任学惠 .嵌入式应用系统教程 北京:人民邮电 出版社 2009 [2]闫锋欣 曾泉人 张志强 译C++ GUI QT4(第二版) 北京:电子 工业出版社 [3]蔡志明 精通Qt4编程 北京:电子工业出版社 [4]王浩南 刘益成 基于嵌入式Linux下的Qt开发 2010 [5] 韦东山 嵌入式Linux应用开发完全手册 北京:人民邮电出版社2008 [6]Linux标准学习教程(第2版)北京:人民邮电出版社2009 [7]陈英,梁建武.Linux基础及应用教程.水利水电出版社2008 [9]刘峥嵘.嵌入式Linux应用开发详解.机械工业出版社,2004 [10]唐新华 Qt 的信号与槽机制介绍 http://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/ 13 因篇幅问题不能全部显示,请点此查看更多更全内容