下载

2下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 1492412

1492412.doc

1492412

mingche_god
2018-09-09 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《1492412doc》,可适用于IT/计算机领域

║嵌入式应用程序开发详解第章Qt图形编程║第章Qt图形编程本章目标  本书从第章到第章详细讲解了嵌入式Linux应用程序的开发这些都是属于用户空间的内容。本章将进入到Linux的内核空间初步介绍嵌入式Linux设备驱动的开发。驱动的开发流程相对于应用程序的开发是全新的希望读者能尽可能地抛弃以前的编程习惯来进行本章的学习。通过本章的学习读者将会掌握以下内容。Linux设备驱动的基本概念Linux设备驱动程序的基本功能Linux设备驱动的运作过程常见设备驱动接口函数掌握LCD设备驱动程序编写步骤掌握键盘设备驱动程序编写步骤嵌入式GUI简介目前的桌面机操作系统大多有着美观、操作方便、功能齐全的GUI(图形用户界面)例如KDE或者GNOME。GUI(图形用户界面)是指计算机与其使用者之间的对话接口可以说GUI是当今计算机技术的重大成就。它的存在为使用者提供了友好便利的界面并大大地方便了非专业用户的使用使得人们从繁琐的命令中解脱出来可以通过窗口、菜单方便地进行操作。而在嵌入式系统中GUI的地位也越来越重要但是不同于桌面机系统嵌入式GUI要求简单、直观、可靠、占用资源小且反应快速以适应系统硬件资源有限的条件。另外由于嵌入式系统硬件本身的特殊性嵌入式GUI应具备高度可移植性与可裁减性以适应不同的硬件条件和使用需求。总体来讲嵌入式GUI具备以下特点:(体积小(运行时耗用系统资源小(上层接口与硬件无关高度可移植(高可靠性(在某些应用场合应具备实时性。UNIX环境下的图形视窗标准为XWindowSystemLinux是类UNIX系统所以顶层运行的GUI系统是兼容X标准的XFree系统。X标准大致可以划分XServer、GraphicLibrary(底层绘图函数库)、Toolkits、WindowManager等几大部分。其好处是具有可扩展性、可移植性等优点但对于嵌入式系统而言无疑太过庞大、累赘、低效。目前流行的嵌入式GUI与X思路不同这些GUI一般不局限于X标准更强调系统的空间和效率。QtEmbedded表归纳了QtEmbedded的一些优缺点。表QtEmbedded分析QtEmbedded分析优点以开发包形式提供包括了图形设计器Makefile制作工具字体国际化工具Qt的C类库等跨平台支持MicrosoftWindows、MicrosoftWindowsNT、MacOSX、LinumySignal但是它携带一个整形参数这有点类似于C中的虚函数。从形式上讲信号的声明与普通的C函数是一样的但是信号却没有函数体定义。另外信号的返回类型都是void。信号由moc自动产生它们不应该在cpp文件中实现。()插槽插槽是普通的C成员函数可以被正常调用它们惟一的特殊性就是很多信号可以与其相关联。当与其关联的信号被发射时这个插槽就会被调用。插槽可以有参数但插槽的参数不能有缺省值。既然插槽是普通的成员函数因此与其他的函数一样它们也有存取权限。插槽的存取权限决定了谁能够与其相关联。同普通的C成员函数一样插槽函数也分为种类型即publicslots、privateslots和protectedslots。(publicslots:在这个区内声明的槽意味着任何对象都可将信号与之相连接。这对于组件编程非常有用用户可以创建彼此互不了解的对象将它们的信号与槽进行连接以便信息能够正确地传递。(protectedslots:在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。这适用于那些槽它们是类实现的一部分但是其界面接口却面向外部。(privateslots:在这个区内声明的槽意味着只有类自己可以将信号与之相连接。这适用于联系非常紧密的类。插槽也能够被声明为虚函数这也是非常有用的。插槽的声明也是在头文件中进行的。例如下面声明了个插槽:publicslots:voidmySlot()voidmySlot(intx)voidmySignalParam(intx,inty)()信号与插槽关联通过调用QObject对象的connect函数可以将某个对象的信号与另外一个对象的插槽函数相或信号相关联当发射者发射信号时接收者的槽函数或信号将被调用。该函数的定义如下所示:boolQObject::connect(constQObject*sender,constchar*signal,constQObject*receiver,constchar*member)static这个函数的作用就是将发射者sender对象中的信号signal与接收者receiver中的member插槽函数联系起来。当指定信号signal时必须使用Qt的宏SIGNAL()当指定插槽函数时必须使用宏SLOT()。如果发射者与接收者属于同一个对象的话那么在connect调用中接收者参数可以省略。(信号与插槽相关联下例定义了两个对象:标签对象label和滚动条对象scroll并将valueChanged()信号与标签对象的setNum()插槽函数相关联另外信号还携带了一个整型参数这样标签总是显示滚动条所处位置的值。QLabel*label=newQLabelQScrollBar*scroll=newQScrollBarQObject::connect(scroll,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)))(信号与信号相关联在下面的构造函数中MyWidget创建了一个私有的按钮aButton按钮的单击事件产生的信号clicked()与另外一个信号aSignal()进行了关联。这样当信号clicked()被发射时信号aSignal()也接着被发射。如下所示:classMyWidget:publicQWidget{public:MyWidget()signals:voidaSignal()private:QPushButton*aButton}MyWidget::MyWidget(){aButton=newQPushButton(this)connect(aButton,SIGNAL(clicked()),SIGNAL(aSignal()))}()解除信号与插槽关联当信号与槽没有必要继续保持关联时用户可以使用disconnect函数来断开连接。其定义如下所示:boolQObject::disconnect(constQObject*sender,constchar*signal,constObject*receiver,constchar*member)static这个函数断开发射者中的信号与接收者中的槽函数之间的关联。有种情况必须使用disconnect()函数。(断开与某个对象相关联的任何对象当用户在某个对象中定义了一个或者多个信号这些信号与另外若干个对象中的槽相关联如果想要切断这些关联的话就可以利用这个方法非常之简洁。如下所示:disconnect(myObject,,,)或者myObject>disconnect()(断开与某个特定信号的任何关联这种情况是非常常见的其典型用法如下所示:disconnect(myObject,SIGNAL(mySignal()),,)或者myObject>disconnect(SIGNAL(mySignal()))(断开两个对象之间的关联这也是非常常用的情况如下所示:disconnect(myObject,,myReceiver,)或者myObject>disconnect(myReceiver)注意在disconnect函数中可以用作一个通配符分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为其他个参数的值可以等于。搭建QtEmbedded开发环境一般来说用QtEmbedded开发的应用程序最终会发布到安装有嵌入式Linux操作系统的小型设备上所以使用装有Linux操作系统的PC机或者工作站来完成QtEmbedded开发当然是最理想的环境此外QtEmbedded也可以安装在UNIX或Windows系统上。这里就以安装到Linux操作系统为例进行介绍。这里需要有个软件安装包:tmake工具安装包QtEmbedded安装包Qt的X版的安装包。(tmake或更高版本:生成QtEmbedded应用工程的Makefile文件。(QtEmbedded:QtEmbedded安装包。(QtforX:Qt的X版的安装包产生x开发环境所需要的两个工具。注意这些软件安装包都有许多不同的版本由于版本的不同会导致这些软件在使用时可能引起的冲突为此必须依照一定的安装原则QtEmbedded安装包的版本必须比QtforX的安装包的版本新这是因为QtforX的安装包中的两个工具uic和designer产生的源文件会和QtEmbedded的库一起被编译链接因此要本着“向前兼容”的原则QtforX的版本应比QtEmbedded的版本旧。.安装tmake用户可使用普通的解压缩即可注意要将路径添加到全局变量中去如下所示:tarzxvftmaketargzexportTMAKEDIR=$PWDtmakeexportTMAKEPATH=$TMAKEDIRlibqwslinuxxgexportPATH=$TMAKEDIRbin:$PATH.安装QtEmbedded这里使用常见的解压命令及安装命令即可要注意这里的路径与不同的系统有关读者要根据实际情况进行修改。另外这里的configure命令带有参数“qconfig–qvfb–depths”分别为指定Qt嵌入式开发包生成虚拟缓冲帧工具qvfb并支持位的显示颜色深度。另外读者也可以在configure的参数中添加“system”、“jpeg”或“gif”命令使QtEmbedded平台能支持jpeg、gif格式的图形。QtEmbedded开发包有种编译范围的选项使用这些选项可控制Qt生成的库文件的大小。如命令makesubsrc指定按精简方式编译开发包也就是说有些Qt类未被编译。其他编译选项的具体用法可参见“configure–help”命令查看。精简方式的安装步骤若下所示:tarzxvfqtembeddedtargzcdqtexportQTDIR=$PWDexportQTEDIR=$QTDIRexportPATH=$QTDIRbin:$PATHexportLDLIBRARYPATH=$QTDIRlib:$LDLIBRARYPATHconfigureqconfiglocalqvfbdepths,,,makesubsrc.安装QtX与上一步类似用户也可以在configure后添加一定的参数如“noopengl”或“noxfs”可以键入命令“configure–help”来获得一些帮助信息。tarxfzqtxtargzcdqtexportQTDIR=$PWDexportPATH=$QTDIRbin:$PATHexportLDLIBRARYPATH=$QTDIRlib:$LDLIBRARYPATHconfigurenoopenglmakemakeCtoolsqvfbmvtoolsqvfbqvfbbincpbinuic$QTEDIRbinQtEmbedded窗口部件QT提供了一整套的窗口部件。它们组合起来可用于创建用户界面的可视元素。按钮、菜单、滚动条、消息框和应用程序窗口都是窗口部件的实例。因为所有的窗口部件既是控件又是容器因此QT的窗口部件不能任意地分为控件和容器。通过子类化已存在的QT部件或少数时候必要的全新创建自定义的窗口部件能很容易地创建出来。窗口部件是QWidget或其子类的实例用户自定义的窗口通过子类化得到。如下图所示:图源自QWidget的类层次结构一个窗口部件可包含任意数量的子部件。子部件在父部件的区域内显示。没有父部件的部件是顶级部件(比如一个窗口)通常在桌面的任务栏上有它们的入口。QT不在窗口部件上施加任何限制。任何部件都可以是顶级部件任何部件都可以是其他部件的子部件。通过自动或手动(如果你喜欢)则使用布局管理器可以设定子部件在父部件区域中的位置。如果父部件被停用隐藏或删除则同样的动作会地应用于它的所有子部件。.Hello窗口实例下面是一个显示“HelloQtEmbedded!”的程序的完整的源代码:#include<qapplicationh>#include<qlabelh>intmain(intargc,char**argv){QApplicationapp(argc,argv)QLabel*hello=newQLabel("<fontcolor=blue>Hello""<i>QtEmbedded!<i><font>",)appsetMainWidget(hello)hello>show()returnappexec()}下图是该Hello窗口的运行效果图:.常见通用窗口组合Qt中还有一些常见的通用窗口它们使用了Windows风格显示。如下图、、、分别描述了常见的一些通用窗口的组合使用。图Hello窗口运行效果图图使用了QHBox进行排列一个标签和一个按钮图使用了QbuttonGroup的两个单选框和两个复选框图QgroupBox组合图示图使用了QgroupBox进行排列的的日期类QdateTimeEdit、一个行编辑框类QlineEdit、一个文本编辑类QTextEdit和一个组合框类QcomboBox。图是以QGrid排列的一个Qdial、一个QprogressBar、一个QspinBox、一个QscrollBar、一个QLCDNumber和一个Qslider。图是以QGrid排列的一个QiconView、一个QlistView、一个QListBox和一个Qtable。图Qgrid组合图示图Qgrid组合图示图钟表部件图示.自定义窗口开发者可以通过子类化QWidget或它的一个子类创建他们自己的部件或对话框。为了举例说明子类化下面提供了数字钟部件的完整代码。钟表部件是一个能显示当前时间并自动更新的LCD。一个冒号分隔符随秒数的流逝而闪烁如图所示。Clock从QLCDNumber部件继承了LCD功能。它有一个典型部件类所拥有的典型构造函数带有可选parent和name参数的(如果设置了name参数测试和调试会更容易)。系统有规律地调用从QObject继承的timerEvent()函数。它在clockh中定义如下所示:#include<qlcdnumberh>classClock:publicQLCDNumber{public:Clock(QWidget*parent=,constchar*name=)protected:voidtimerEvent(QTimerEvent*event)private:voidshowTime()boolshowingColon}构造函数调showTime()是用当前时间初始化钟表并且告诉系统每毫秒调用一次timerEvent()来刷新LCD的显示。在showTime()中通过调用QLCDNumber::display()来显示当前时间。每次调用showTime()来让冒号闪烁时冒号就被空白代替。clockcpp的源码如下所示:#include<qdatetimeh>#include"clockh"Clock::Clock(QWidget*parent,constchar*name):QLCDNumber(parent,name),showingColon(true){showTime()startTimer()}voidClock::timerEvent(QTimerEvent*){showTime()}voidClock::showTime(){QStringtimer=QTime::currentTime()toString()left()if(!showingColon)time=''display(time)showingColon=!showingColon}文件clockh和clockcpp完整地声明并实现了Clock部件。#include<qapplicationh>#include"clockh"intmain(intargc,char**argv){QApplicationapp(argc,argv)Clock*clock=newClockappsetMainWidget(clock)clock>show()returnappexec()}QtEmbedded图形界面编程Qt提供了所有可能的类和函数来创建GUI程序。Qt既可用来创建“主窗口”式的程序即一个有菜单栏工具栏和状态栏作为环绕的中心区域也可以用来创建“对话框”式的程序使用按钮和必要的选项卡来呈现选项与信息。Qt支持SDI(单文档界面)和MDI(多文档界面)。Qt还支持拖动放下和剪贴板。工具栏可以在工具栏区域内移动拖拽到其他区域或者作为工具托盘浮动起来。这个功能是内建的不需要额外的代码但程序员在需要时可以将约束工具栏的行为。使用Qt可以大大简化编程程序。例如如果一个菜单项一个工具栏按钮和一个快捷键都完成同样的动作那么这个动作只需要一份代码。Qt还提供消息框和一系列标准对话框使得程序向用户提问和让用户选择文件、文件夹、字体以及颜色变得更加简单。为了呈现一个消息框或一个标准对话框只需要用一个使用一个方便的Qt静态函数的一行的语句。.主窗口类QMainWindow类提供了一个典型应用程序的主窗口框架。一个主窗口包含了一组标准窗体的集合。主窗口的顶部包含一个菜单栏它的下方放置着一个工具栏工具栏可以移动到其他的停靠区域。主窗口允许停靠的位置有顶部、左边、右边和底部。工具栏可以被拖放到一个停靠的位置从而形成一个浮动的工具面板。主窗口的下方也就是在底部的停靠位置下方有一个状态栏。主窗口的中间区域可以包含其他的窗体。提示工具和“这是什么”帮助按钮以旁述的方式阐述了用户接口的使用方法。对于小屏幕的设备使用Qt图形设计器定义的标准的Qwidget模板比使用主窗口类更好一些。典型的模板包含有菜单栏、工具栏可能没有状态栏(在必要的情况下可以用任务栏标题栏来显示状态)。例如一个文本编辑器可以把QTextEdit作为中心部件:QTextEdit*editor=newQTextEdit(mainWindow)mainWindow>setCentralWidget(editor).菜单类弹出式菜单QpopupMenu类以垂直列表的方式显示菜单项它可以是单个的(例如上下文相关菜单)可以以菜单栏的方式出现或者是别的弹出式菜单的子菜单出现。每个菜单项可以有一个图标一个复选框和一个加速器(快捷键)菜单项通常对应一个动作(例如存盘)分隔器通常显示成一条竖线它用于把一组相关联的动作菜单分立成组。下面是一个建立包含有NewOpen和Exit菜单项的文件菜单的例子。QPopupMenu*fileMenu=newQPopupMenu(this)fileMenu>insertItem("New",this,SLOT(newFile()),CTRLKeyN)fileMenu>insertItem("Open",this,SLOT(open()),CTRLKeyO)fileMenu>insertSeparator()fileMenu>insertItem("Exit",qApp,SLOT(quit()),CTRLKeyQ)当一个菜单项被选中和它相关的插槽将被执行。加速器(快捷键)很少在一个没有键盘输入的设备上使用QtEmbedded的典型配置并未包含对加速器的支持。上面出现的代码“New”意思是在桌面机器上以“New”的方式显示出来但是在嵌入式设备中它只会显示为“New”。QmenuBar类实现了一个菜单栏它会自动地设置几何尺寸并在它的父窗体的顶部显示出来如果父窗体的宽度不够宽以至不能显示一个完整的菜单栏那么菜单栏将会分为多行显示出来。Qt内置的布局管理能够自动调整菜单栏。Qt的菜单系统是非常灵活的菜单项可以被动态使能失效添加或者删除。通过子类化QcustomMenuItem用户可以建立客户化外观和功能的菜单项。.工具栏工具栏可以被移动到中心区域的顶部、底部、左边或右边。任何工具栏都可以拖拽到工具栏区域的外边作为独立的浮动工具托盘。QtoolButton类实现了具有一个图标一个D框架和一个可选标签的工具栏。切换型工具栏按钮具有可以打开或关闭某些特征。其他的则会执行一个命令。可以为活动、关闭、开启等模式打开或关闭等状态提供不同的图标。如果只提供一个图标Qt能根据可视化线索自动地辨别状态例如将禁用的按钮变灰工具栏按钮也能触发弹出式菜单。QToolButton通常在QToolBar内并排出现。一个程序可含有任意数量的工具栏并且用户可以自由地移动它们。工具栏可以包括几乎所有部件例如QComboBox和QSpinBox。.旁述现在的应用主要使用旁述的方式去解释用户接口的用法。Qt提供了两种旁述的方式即“提示栏”和“这是什么”帮助按钮。(“提示栏”是小的通常是黄色的矩形当鼠标在窗体的某些位置游动时它就会自动地出现。它主要用于解释工具栏按钮特别是那些缺少文字标签说明的工具栏按钮的用途。下面就是如何设置一个“存盘”按钮的提示代码。QToolTip::add(saveButton,"Save")当提示字符出现之后还可以在状态栏显示更详细的文字说明。对于一些没有鼠标的设备(例如那些使用触点输入的设备)就不会出现鼠标的光标在窗体上进行游动这样就不能激活提示栏。对于这些设备也许就需要使用“这是什么”帮助按钮或者使用一种姿态来表示输入设备正在进行游动例如用按下或者握住的姿态来表示现在正在进行游动。(“这是什么”帮助按钮和提示栏有些相似只不过前者是要用户单击它才会显示旁述。在小屏幕设备上要想单击“这是什么”帮助按钮具体的方法是在靠近应用的X窗口的关闭按钮“x”附近你会看到一个“?”符号的小按钮这个按钮就是“这是什么”的帮助按钮。一般来说“这是什么”帮助按钮按下后要显示的提示信息应该比提示栏要多一些。下面是设置一个存盘按钮的“这是什么”文本提示信息的方法:QWhatsThis::add(saveButton,"Savesthecurrentfile")QToolTip和QWhatsThis类提供了可以通过重新实现来获取更多特殊化行为的虚函数比如根据鼠标在部件的位置来显示不同的文本。.动作应用程序通常提供几种不同的方式来执行特定的动作。比如许多应用程序通过菜单(Flie>Save)工具栏(像一个软盘的按钮)和快捷键(CtrlS)来提供“Save”动作。QAction类封装了“动作”这个概念。它允许程序员在某个地方定义一个动作。下面的代码实现了一个“Save”菜单项一个“Save”工具栏按钮和一个“Save”快捷键并且均有旁述帮助:QAction*saveAct=newQAction("Save",saveIcon,"Save",CTRLKeyS,this)connect(saveAct,SIGNAL(activated()),this,SLOT(save()))saveAct>setWhatsThis("Savesthecurrentfile")saveAct>addTo(fileMenu)saveAct>addTo(toolbar)为了避免重复使用QAction可保证菜单项的状态与工具栏保持同步而工具提示能在需要的时候显示。禁用一个动作会禁用相应的菜单项和工具栏按钮。类似地当用户单击切换型按钮时相应的菜单项会因此被选中或不选。QtEmbedded对话框设计QtEmbedded对话框的设计比较复杂要使用布局管理自动地设置窗体与别的窗体之间相对的尺寸和位置这样可以确保对话框能够最好地利用屏幕上的可用空间接着还要使用Qt图形设计器地可视化设计工具建立对话框。下面就详细讲解具体的步骤。.布局Qt的布局管理用于组织管理一个父窗体区域内的子窗体。它的特点是可以自动设置子窗体的位置和大小并可确定出一个顶级窗体的最小和缺省的尺寸当窗体的字体或内容变化后它可以重置一个窗体的布局。使用布局管理开发者可以编写独立于屏幕大小和方向之外的程序从而不需要浪费代码空间和重复编写代码。对于一些国际化的应用程序使用布局管理可以确保按钮和标签在不同的语言环境下有足够的空间显示文本不会造成部分文字被剪掉。布局管理提供部分用户接口组件例如输入法和任务栏变得更容易。我们可以通过一个例子说明这一点当Qtopia的用户输入文字时输入法会占用一定的文字空间应用程序这时也会根据可用屏幕尺寸的变化调整自己。Qtopia的布局管理示例图如图所示。()内建布局管理器Qt提供了种用于布局管理的类:QHBoxLayoutQVBoxLayout和QgridLayout。(QHBoxLayout布局管理把窗体按照水平方向从左至右排成一行。(QVBoxLayout布局管理把窗体按照垂直方向从上至下排成一列。(QGridLayout布局管理以网格的方式来排列窗体一个窗体可以占据多个网格。它们的示意图如图所示。在多数情况下Qt的布局管理器为其管理的部件挑选一个最适合的尺寸以便窗口能够平滑地缩放。如果其缺省值不合适开发者可以使用以下机制微调布局:(设置一个最小尺寸一个最大尺寸或者为一些子部件设置固定的大小。图种布局管理类示意图(设置一些延伸项目或间隔项目延伸或间隔项目会填充空余的布局空间。(改变子部件的尺寸策略。通过调用QWidget::setSizePolicy()程序员可以仔细调整子部件的缩放行为。子部件可以设置为扩展、收缩、保持原大小等状态。(改变子部件的建议大小。QWidget::sizeHint()和QWidget::minimumSizeHint()会根据内容返回部件的首选尺寸和最小首选尺寸。内建部件提供了合适的重新实现。(设置延伸因子。延伸因子规定了子部件的相应增量比如的可用空间分配给部件A而三分之一分配给B。()布局嵌套布局可以嵌套任意层。图显示了一个对话框的两种大小。图一个对话框的两种大小这个对话框使用了种布局:一个QVBoxLayout组合了按钮一个QHBoxLayout组合了国家列表和那组按钮一个QVBoxLayout组合了“Selectacountry”标签和剩下的部件。一个延伸项目用来维护Cancel和Help按钮间的距离。下面的代码创建了对话框部件和布局:QVBoxLayout*buttonBox=newQVBoxLayout()buttonBox>addWidget(newQPushButton("OK",this))buttonBox>addWidget(newQPushButton("Cancel",this))buttonBox>addStretch()buttonBox>addWidget(newQPushButton("Help",this))QListBox*countryList=newQListBox(this)countryList>insertItem("Canada")**countryList>insertItem("UnitedStatesofAmerica")QHBoxLayout*middleBox=newQHBoxLayout()middleBox>addWidget(countyList)middleBox>addLayout(buttonBox)QVBoxLayout*topLevelBox=newQVBoxLayout(this,,)topLevelBox>addWidget(newQLabel("Selectacountry",this))topLevelBox>addLayout(middleBox)可以看到Qt让布局变得非常容易。()自定义布局通过子类化QLayout开发者可以定义自己的布局管理器。和Qt一起提供的customlayout样例展示了三个自定义布局管理器:BorderLayout、CardLayout和SimpleFlow程序员可以使用并修改它们。Qt还包括QSplitter是一个最终用户可以操纵的分离器。某些情况下QSplitter可能比布局管理器更为可取。为了完全控制重新实现每个子部件的QWidget::resizeEvent()并调用QWidget::setGeometry()就可以在一个部件中手动地实现布局。.QtEmbedded图形设计器Qt图形设计器是一个具有可视化用户接口的设计工具。Qt的应用程序可以完全用源代码来编写或者使用Qt图形设计器来加速开发工作。启动Qt图形设计器的方法是:cdqtbindesigner这样就可以启动一个图形化的设计界面如图所示。开发者单击工具栏上的代表不同功能的子窗体组件的按钮然后把它放到一个表单上这样就可以把一个子窗体组件放到表单上了。开发者可以使用属性对话框来设置子窗体的属性精确地设置子窗体的位置和尺寸大小是没必要的。开发者可以选择一组窗体然后对他们进行排列。例如我们选定了一些按钮窗体然后使用“水平排列(layouthorizontally)”选项对它们进行一个接一个的水平排列。这样做不仅使得设计工作变得更快而且完成后的窗体将能够按照属性设置的比例填充窗口的可用尺寸范围。图Qt图形设计器界面使用Qt图形设计器进行图形用户接口的设计可以消除应用的编译、链接和运行时间同时使修改图形用户接口的设计变得更容易。Qt图形设计器的预览功能可以使开发者能够在开发阶段看到各种样式的图形用户界面也包括客户样式的用户界面。通过Qt集成功能强大的数据库类Qt图形设计器还可提供生动的数据库数据浏览和编辑操作。开发者可以建立同时包含有对话框和主窗口的应用其中主窗口可以放置菜单工具栏旁述帮助等的子窗口部件。Qt图形设计器提供了几种表单模板如果窗体会被多个不同的应用反复使用那么开发者也可建立自己的表单模板以确保窗体的一致性。Qt图形设计器使用向导来帮助人们更快更方便地建立包含有工具栏、菜单和数据库等方面的应用。程序员可以建立自己的客户窗体并把它集成到Qt图形设计器中。Qt图形设计器设计的图形界面以扩展名为“ui”的文件进行保存这个文件有良好的可读性这个文件可被uic(Qt提供的用户接口编译工具)编译成为C的头文件和源文件。Qmake工具在它为工程生成的Makefile文件中自动包含了uic生成头文件和源文件的规则。另一种可选的做法是在应用程序运行期间载入ui文件然后把它转变为具备原先全部功能的表单。这样开发者就可以在程序运行期间动态地修改应用的界面而不需重新编译应用另一方面也使得应用的文件尺寸减小了。.建立对话框Qt为许多通用的任务提供了现成的包含了实用的静态函数的对话框类主要有以下几种。(QmessageBox类:是一个用于向用户提供信息或是给用户进行一些简单选择(例如“yes”或“no”)的对话框类。如图所示。(progressDialog类:包含了一个进度栏和一个“Cancel”按钮。如图所示。(Qwizard类:提供了一个向导对话框的框架。如图所示。图QmessageBox类对话框图progressDialog类对话框图Qwizard类对话框另外Qt提供的对话框还包括QcolorDialog、QfileDialog、QFontDialog和QprintDialog。这些类通常适用于桌面应用一般不会在QtEmbedded中编译使用它们。实验内容使用Qt编写“HelloWorld”程序.实验目的通过编写一个跳动的“Hello,World”字符串进一步熟悉嵌入式Qt的开发过程。.实验步骤()生成一个工程文件(pro文件)使用命令progen产生一个工程文件(progen程序可在tmake的安装路径下找到)。如下所示:progen–tappt–ohellopro那样产生的hellopro工程文件并不完整开发者还需添加工程所包含的头文件源文件等信息。()新建一个窗体启动Qt图形编辑器使用如下命令:designer(该程序在qtxforx的安装路径的bin目录下)接着单击编辑器的“new”菜单弹出了一个“newForm”对话框在这个对话框里选择“Widget”然后单击“OK”按钮这样就新建了一个窗体。接下来再对这个窗体的属性进行设置注意把窗体的“name”属性设为“Hello”窗体的各种尺寸设为宽“”高“”目的是使窗体大小和FS带的显示屏的大小一致窗体背景颜色设置为白色。具体设置如图所示。图Hello窗体的属性设置设置完成后将其保存为helloui文件这个文件就是Hello窗体的界面存储文件。()生成Hello窗体类的头文件和实现文件下面根据上述的界面文件helloui使用uic工具产生Hello窗体类的头文件和实现文件具体方法是:cdqtbinuic–ohellohhellouiuic–ohellocpp–implhellohhelloui这样就得到了Hello窗体类的头文件helloh和实现文件hellocpp。下面就可以根据需要实现的具体功能在hellocpp文件里添加相应的代码。比如要在Hello的窗体上显示一个动态的字符串“HelloWorld”那么使用需要重新实现paintEvent(QPaintEvent*)方法同时还需要添加一个定时器Qtimer实例以周期性刷新屏幕从而得到动画得效果。下面是修改后的helloh和hellocpp文件。******************************************************************************以下是helloh的代码****************************************************************************#ifndefHELLOH#defineHELLOH#include<qvarianth>#include<qwidgeth>classQVBoxLayoutclassQHBoxLayoutclassQGridLayoutclassHello:publicQWidget{QOBJECTpublic:Hello(QWidget*parent=,constchar*name=,WFlagsfl=)~Hello()以下是手动添加的代码signals:voidclicked()protected:voidmouseReleaseEvent(QMouseEvent*)voidpaintEvent(QPaintEvent*)privateslots:voidanimate()private:QStringtintb}#endifHELLOH******************************************************************************以下是hellocpp源代码****************************************************************************#include"helloh"#include<qlayouth>#include<qvarianth>#include<qtooltiph>#include<qwhatsthish>#include<qpushbuttonh>#include<qtimerh>#include<qpainterh>#include<qpixmaph>**ConstructsaHellowhichisachildof'parent',withthe*name'name'andwidgetflagssetto'f'*Hello::Hello(QWidget*parent,constchar*name,WFlagsfl):QWidget(parent,name,fl){if(!name)setName("Hello")resize(,)setMinimumSize(QSize(,))setMaximumSize(QSize(,))setSizeIncrement(QSize(,))setBaseSize(QSize(,))QPalettepalQColorGroupcgcgsetColor(QColorGroup::Foreground,black)cgsetColor(QColorGroup::Button,QColor(,,))cgsetColor(QColorGroup::Light,white)cgsetColor(QColorGroup::Midlight,QColor(,,))cgsetColor(QColorGroup::Dark,QColor(,,))cgsetColor(QColorGroup::Mid,QColor(,,))cgsetColor(QColorGroup::Text,black)cgsetColor(QColorGroup::BrightText,white)cgsetColor(QColorGroup::ButtonText,black)cgsetColor(QColorGroup::Base,white)cgsetColor(QColorGroup::Background,white)cgsetColor(QColorGroup::Shadow,black)cgsetColor(QColorGroup::Highlight,black)cgsetColor(QColorGroup::HighlightedText,white)palsetActive(cg)cgsetColor(QColorGroup::Foreground,black)cgsetColor(QColorGroup::Button,QColor(,,))cgsetColor(QColorGroup::Light,white)cgsetColor(QColorGroup::Midlight,QColor(,,))cgsetColor(QColorGroup::Dark,QColor(,,))cgsetColor(QColorGroup::Mid,QColor(,,))cgsetColor(QColorGroup::Text,black)cgsetColor(QColorGroup::BrightText,white)cgsetColor(QColorGroup::ButtonText,black)cgsetColor(QColorGroup::Base,white)cgsetColor(QColorGroup::Background,white)cgsetColor(QColorGroup::Shadow,black)cgsetColor(QColorGroup::Highlight,black)cgsetColor(QColorGroup::HighlightedText,white)palsetInactive(cg)cgsetColor(QColorGroup::Foreground,QColor(,,))cgsetColor(QColorGroup::Button,QColor(,,))cgsetColor(QColorGroup::Light,white)cgsetColor(QColorGroup::Midlight,QColor(,,))cgsetColor(QColorGroup::Dark,QColor(,,))cgsetColor(QColorGroup::Mid,QColor(,,))cgsetColor(QColorGroup::Text,black)cgsetColor(QColorGroup::BrightText,white)cgsetColor(QColorGroup::ButtonText,QColor(,,))cgsetColor(QColorGroup::Base,white)cgsetColor(QColorGroup::Background,white)cgsetColor(QColorGroup::Shadow,black)cgsetColor(QColorGroup::Highlight,black)cgsetColor(QColorGroup::HighlightedText,white)palsetDisabled(cg)setPalette(pal)QFontf(font())fsetFamily("adobehelvetica")fsetPointSize()fsetBold(TRUE)setFont(f)setCaption(tr(""))以下是手动添加的代码t="Hello,World"b=QTimer*timer=newQTimer(this)connect(timer,SIGNAL(timeout()),SLOT(animate()))timer>start()}**Destroystheobjectandfreesanyallocatedresources*Hello::~Hello(){}以下至结尾是手动添加的代码voidHello::animate(){b=(b)repaint(FALSE)}*HandlesmousebuttonreleaseeventsfortheHellowidgetWeemittheclicked()signalwhenthemouseisreleasedinsidethewidget*voidHello::mouseReleaseEvent(QMouseEvent*e){if(rect()contains(e>pos()))emitclicked()}*HandlespainteventsfortheHellowidgetFlickerfreeupdateThetextisfirstdrawninthepixmapandthepixmapisthenblt'edtothescreen*voidHello::paintEvent(QPaintEvent*){staticintsintbl={,,,,,,,,,,,,,,,}if(tisEmpty())return:Computesomesizes,positionsetcQFontMetricsfm=fontMetrics()intw=fmwidth(t)inth=fmheight()*intpmx=width()wintpmy=height()h:Createthepixmapandfillitwiththewidget'sbackgroundQPixmappm(w,h)pmfill(this,pmx,pmy):PaintthepixmapCoolwaveeffectQPainterpintx=inty=hfmdescent()inti=pbegin(pm)psetFont(font())while(!tiis()){inti=(bi)psetPen(QColor((i)*,,,QColor::Hsv))pdrawText(x,ysintbli*h,tmid(i,),)x=fmwidth(ti)i}pend():CopythepixmaptotheHellowidgetbitBlt(this,pmx,pmy,pm)}()编写主函数main()一个QtEmbeded应用程序应该包含一个主函数主函数所在的文件名是maincpp。主函数是应用程序执行的入口点。以下是“Hello,World”例子的主函数文件maincpp的实现代码:******************************************************************************以下是maincpp源代码****************************************************************************#include"helloh"#include<qapplicationh>*TheprogramstartshereItparsesthecommandlineandbuildsamessagestringtobedisplayedbytheHellowidget*#defineQTNOWIZARDintmain(intargc,char**argv){QApplicationa(argc,argv)HellodlgQObject::connect(dlg,SIGNAL(clicked()),a,SLOT(quit()))asetMainWidget(dlg)dlgshow()returnaexec()}()编辑工程文件hellopro文件到目前为止为Hello,World例子编写了一个头文件和两个源文件这个文件应该被包括在工程文件中因此还需要编辑hellopro文件加入这helloh,hellocpp,maincpp这三个文件名。具体定义如下:******************************************************************************以下是hellopro文件的内容****************************************************************************TEMPLATE=appCONFIG=qtwarnonreleaseHEADERS=hellohSOURCES=hellocppmaincppINTERFACES=()生成Makefile文件编译器是根据Makefile文件内容来进行编译的所以需要生成Makefile文件。Qt提供的tmake工具可以帮助我们从一个工程文件(pro文件)中产生Makefile文件。结合当前例子要从hellopro生成一个Makefile文件的做法是首先查看环境变量$TMAKEPATH是否指向arm编译器的配置目录在命令行下输入以下命令:echo$TMAKEPATH如果返回的结果末尾不是…qwslinuxarmg的字符串那您需要把环境变量$TMAKEPATH所指的目录设置为指向arm编译器的配置目录过程如下exportTMAKEPATH=tmake安装路径qwslinuxarmg同时应确保当前的QTDIR环境变量指向QtEmbedded的安装路径,如果不是则需要执行以下过程。exportQTDIR=……qt上述步骤完成后就可以使用tmake生成Makefile文件具体做法是在命令行输入以下命令:tmake–oMakefilehellopro这样就可以看到当前目录下新生成了一个名为Makefile的文件。下一步需要打开这个文件做一些小的修改。)将LINK=armlinuxgcc这句话改为:LINK=armlinuxg这样做是因为要是用armlinuxg进行链接。)将LIBS=$(SUBLIBS)L$(QTDIR)liblm–lqte这句话改为:LIBS=$(SUBLIBS)LusrlocalarmlibL$(QTDIR)liblm–lqte这是因为链接时要用到交叉编译工具toolchain的库。()编译链接整个工程最后就可以在命令行下输入make命令对整个工程进行编译链接了。makemake生成的二进制文件hello就是可以在FS上运行的可执行文件。本章小结本章主要讲解了嵌入式Linux的图形编程。首先介绍了几种常见的嵌入式图形界面编程机制并给出了它们之间的相互关系。接下来本章介绍了QtEmbedded了开发入门包括环境的搭建、信号与插槽的概念与应用以及图形设计器的应用。本章的实验介绍了如何使用Qt编写“HelloWorld”小程序从中可以了解到Qt编程过程的全过程。�图Qtopia的布局管理�EMBEDWordPicture���图QtEmbedded与Qt�X的Linux版本的比较doc对象插槽插槽对象信号插槽插槽对象信号信号doc应用源代码QtAPIQtEmbeddedQtXQtXLibXWindowServer帧缓冲Linux内核vsd�QObject�QWidget�QSpinBox�QFrameQDialogQLabelQLineEditQTime

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/29

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利