当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]通过编写一个跳动的“Hello,World”字符串,进一步熟悉嵌入式Qt的开发过程。

12.3实验内容——使用Qt编写“Hello,World”程序1.实验目的

通过编写一个跳动的“Hello,World”字符串,进一步熟悉嵌入式Qt的开发过程。

2.实验步骤

(1)生成一个工程文件(.pro文件)。

使用命令progen产生一个工程文件(progen程序可在tmake的安装路径下找到)。

如下所示:

progen–tapp.t–ohello.pro

那样产生的hello.pro工程文件并不完整,开发者还需添加工程所包含的头文件,源文件等信息。

(2)新建一个窗体。

启动Qt图形编辑器,使用如下命令:

./designer(该程序在qt-2.3.xforx11的安装路径的bin目录下)

接着单击编辑器的“new”菜单,弹出了一个“newForm”对话框,在这个对话框里选择“Widget”,然后单击“OK”按钮,这样就新建了一个窗体。

接下来再对这个窗体的属性进行设置,注意把窗体的“name”属性设为“Hello”;窗体的各种尺寸设为宽“240”、高“320”,目的是使窗体大小和FS2410带的显示屏的大小一致;窗体背景颜色设置为白色。具体设置如图12.18所示。

图12.18Hello窗体的属性设置

设置完成后,将其保存为hello.ui文件,这个文件就是Hello窗体的界面存储文件。

(3)生成Hello窗体类的头文件和实现文件。

下面根据上述的界面文件hello.ui使用uic工具产生Hello窗体类的头文件和实现文件,具体方法是:

$cdqt-2.3.7/bin

$uic–ohello.hhello.ui

$uic–ohello.cpp–implhello.hhello.ui

这样就得到了Hello窗体类的头文件hello.h和实现文件hello.cpp。下面就可以根据需要实现的具体功能,在hello.cpp文件里添加相应的代码。

比如要在Hello的窗体上显示一个动态的字符串“Hello,World”,那么需要重新实现paintEvent(QPaintEvent*)方法,同时还需要添加一个定时器QTimer实例,以周期性刷新屏幕,从而得到动画的效果。下面是修改后的hello.h和hello.cpp文件。

/****************************************************************************

**以下是hello.h的代码

****************************************************************************/

#ifndefHELLO_H

#defineHELLO_H

#include<qvariant.h>

#include<qwidget.h>

classQVBoxLayout;

classQHBoxLayout;

classQGridLayout;

classHello:publicQWidget

{

Q_OBJECT

public:

Hello(QWidget*parent=0,constchar*name=0,WFlagsfl=0);

~Hello();

/*以下是手动添加的代码*/

signals:

voidclicked();

protected:

voidmouseReleaseEvent(QMouseEvent*);

voidpaintEvent(QPaintEvent*);

privateslots:

voidanimate();

private:

QStringt;

intb;

};

#endif//HELLO_H

/****************************************************************************

**以下是hello.cpp源代码

****************************************************************************/

#include"hello.h"

#include<qlayout.h>

#include<qvariant.h>

#include<qtooltip.h>

#include<qwhatsthis.h>

#include<qpushbutton.h>

#include<qtimer.h>

#include<qpainter.h>

#include<qpixmap.h>

/*

*ConstructsaHellowhichisachildof'parent',withthe

*name'name'andwidgetflagssetto'f'

*/

Hello::Hello(QWidget*parent,constchar*name,WFlagsfl)

:QWidget(parent,name,fl)

{

if(!name)

setName("Hello");

resize(240,320);

setMinimumSize(QSize(240,320));

setMaximumSize(QSize(240,320));

setSizeIncrement(QSize(240,320));

setBaseSize(QSize(240,320));

QPalettepal;

QColorGroupcg;

cg.setColor(QColorGroup::Foreground,black);

cg.setColor(QColorGroup::Button,QColor(192,192,192));

cg.setColor(QColorGroup::Light,white);

cg.setColor(QColorGroup::Midlight,QColor(223,223,223));

cg.setColor(QColorGroup::Dark,QColor(96,96,96));

cg.setColor(QColorGroup::Mid,QColor(128,128,128));

cg.setColor(QColorGroup::Text,black);

cg.setColor(QColorGroup::BrightText,white);

cg.setColor(QColorGroup::ButtonText,black);

cg.setColor(QColorGroup::Base,white);

cg.setColor(QColorGroup::Background,white);

cg.setColor(QColorGroup::Shadow,black);

cg.setColor(QColorGroup::Highlight,black);

cg.setColor(QColorGroup::HighlightedText,white);

pal.setActive(cg);

cg.setColor(QColorGroup::Foreground,black);

cg.setColor(QColorGroup::Button,QColor(192,192,192));

cg.setColor(QColorGroup::Light,white);

cg.setColor(QColorGroup::Midlight,QColor(220,220,220));

cg.setColor(QColorGroup::Dark,QColor(96,96,96));

cg.setColor(QColorGroup::Mid,QColor(128,128,128));

cg.setColor(QColorGroup::Text,black);

cg.setColor(QColorGroup::BrightText,white);

cg.setColor(QColorGroup::ButtonText,black);

cg.setColor(QColorGroup::Base,white);

cg.setColor(QColorGroup::Background,white);

cg.setColor(QColorGroup::Shadow,black);

cg.setColor(QColorGroup::Highlight,black);

cg.setColor(QColorGroup::HighlightedText,white);

pal.setInactive(cg);

cg.setColor(QColorGroup::Foreground,QColor(128,128,128));

cg.setColor(QColorGroup::Button,QColor(192,192,192));

cg.setColor(QColorGroup::Light,white);

cg.setColor(QColorGroup::Midlight,QColor(220,220,220));

cg.setColor(QColorGroup::Dark,QColor(96,96,96));

cg.setColor(QColorGroup::Mid,QColor(128,128,128));

cg.setColor(QColorGroup::Text,black);

cg.setColor(QColorGroup::BrightText,white);

cg.setColor(QColorGroup::ButtonText,QColor(128,128,128));

cg.setColor(QColorGroup::Base,white);

cg.setColor(QColorGroup::Background,white);

cg.setColor(QColorGroup::Shadow,black);

cg.setColor(QColorGroup::Highlight,black);

cg.setColor(QColorGroup::HighlightedText,white);

pal.setDisabled(cg);

setPalette(pal);

QFontf(font());

f.setFamily("adobe-helvetica");

f.setPointSize(29);

f.setBold(TRUE);

setFont(f);

setCaption(tr(""));

/*以下是手动添加的代码*/

t="Hello,World";

b=0;

QTimer*timer=newQTimer(this);

connect(timer,SIGNAL(timeout()),SLOT(animate()));

timer->start(40);

}

/*

*Destroystheobjectandfreesanyallocatedresources

*/

Hello::~Hello()

{

}

/*以下至结尾是手动添加的代码*/

voidHello::animate()

{

b=(b+1)&15;

repaint(FALSE);

}

/*

HandlesmousebuttonreleaseeventsfortheHellowidget.

Weemittheclicked()signalwhenthemouseisreleasedinside

thewidget.

*/

voidHello::mouseReleaseEvent(QMouseEvent*e)

{

if(rect().contains(e->pos()))

emitclicked();

}

/*HandlespainteventsfortheHellowidget.

Flicker-freeupdate.Thetextisfirstdrawninthepixmapandthe

pixmapisthenblt'edtothescreen.

*/

voidHello::paintEvent(QPaintEvent*)

{

staticintsin_tbl[16]={0,38,71,92,100,92,

71,38,0,-38,-71,-92,-100,-92,-71,-38};

if(t.isEmpty())

eturn;

/*1:Computesomesizes,positionsetc.*/

QFontMetricsfm=fontMetrics();

intw=fm.width(t)+20;

inth=fm.height()*2;

intpmx=width()/2-w/2;

intpmy=height()/2-h/2;

/*2:Createthepixmapandfillitwiththewidget'sbackground*/

QPixmappm(w,h);

pm.fill(this,pmx,pmy);

/*3:Paintthepixmap.Coolwaveeffect*/

QPainterp;

intx=10;

inty=h/2+fm.descent();

inti=0;

p.begin(&pm);

p.setFont(font());

while(!t[i].isNull())

{

nti16=(b+i)&15;

.setPen(QColor((15-i16)*16,255,255,QColor::Hsv));

wText(x,y-sin_tbl[i16]*h/800,t.mid(i,1),1);

+=fm.width(t[i]);

+;

}

p.end();

/*4:CopythepixmaptotheHellowidget*/

bitBlt(this,pmx,pmy,&pm);

}

(4)编写主函数main()。

一个Qt/Embeded应用程序应该包含一个主函数,主函数所在的文件名是main.cpp。主函数是应用程序执行的入口点。以下是“Hello,World”例子的主函数文件main.cpp的实现代码:

/****************************************************************************

**以下是main.cpp源代码

****************************************************************************/

#include"hello.h"

#include<qapplication.h>

/*

Theprogramstartshere.Itparsesthecommandlineandbuildsamessage

stringtobedisplayedbytheHellowidget.

*/

#defineQT_NO_WIZARD

intmain(intargc,char**argv)

{

QApplicationa(argc,argv);

Hellodlg;

QObject::connect(&dlg,SIGNAL(clicked()),&a,SLOT(quit()));

a.setMainWidget(&dlg);

dlg.show();

returna.exec();

}

(5)编辑工程文件hello.pro文件。

到目前为止,为Hello,World例子编写了一个头文件和两个源文件,这3个文件应该被包括在工程文件中,因此还需要编辑hello.pro文件,加入hello.h、hello.cpp、main.cpp这3个文件名。具体定义如下:

/****************************************************************************

**以下是hello.pro文件的内容

****************************************************************************/

TEMPLATE=app

CONFIG=qtwarn_onrelease

HEADERS=hello.h

SOURCES=hello.cpp\

main.cpp

INTERFACES=

(6)生成Makefile文件。

编译器是根据Makefile文件内容来进行编译的,所以需要生成Makefile文件。Qt提供的tmake工具可以帮助我们从一个工程文件(.pro文件)中产生Makefile文件。结合当前例子,要从hello.pro生成一个Makefile文件的做法是首先查看环境变量$TMAKEPATH是否指向ARM编译器的配置目录,在命令行下输入以下命令:

ECHO$TMAKEPATH

如果返回的结果末尾不是…/qws/linux-arm-g++的字符串,那么需要把环境变量$TMAKEPATH所指的目录设置为指向arm编译器的配置目录,过程如下:

EXPORTTMAKEPATH=/TMAKE安装路径/QWS/LINUX-ARM-G++

同时,应确保当前的QTDIR环境变量指向Qt/Embedded的安装路径,如果不是,则需要执行以下过程。

EXPORTQTDIR=……/qt-2.3.7

上述步骤完成后,就可以使用tmake生成Makefile文件,具体做法是在命令行输入以下命令:

TMAKE–OMAKEFILEHELLO.PRO

这样就可以看到当前目录下新生成了一个名为Makefile的文件。下一步,需要打开这个文件,做一些小的修改。

①将LINK=arm-linux-gcc改为:LINK=arm-linux-g++

这样做是因为要用arm-linux-g++进行链接。

②将LIBS=$(SUBLIBS)-L$(QTDIR)/lib-lm–lqte改为:

LIBS=$(SUBLIBS)-L/usr/local/arm/2.95.3/lib-L$(QTDIR)/lib-lm–lqte

这是因为链接时要用到交叉编译工具toolchain的库。

(7)编译链接整个工程。

最后就可以在命令行下输入make命令对整个工程进行编译链接了。

make生成的二进制文件hello就是可以在FS2410上运行的可执行文件。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在Linux系统中,当开发者使用mmap()系统调用将磁盘文件映射到进程的虚拟地址空间时,一个看似简单的指针操作背后,隐藏着操作系统内核与硬件协同工作的复杂机制。这种机制不仅突破了传统文件IO的效率瓶颈,更重新定义了内存...

关键字: Linux 文件IO 内存映射

在Linux驱动开发领域,持续集成与持续部署(CI/CD)流水线通过自动化流程将代码变更快速转化为可靠部署,而KernelCI与LTP测试套件的深度集成则成为保障驱动稳定性的关键技术组合。本文将从原理分析、应用场景及实现...

关键字: CICD流水线 Linux

深圳2026年2月6日 /美通社/ -- 近日,汇顶科技eSIM方案成功获得GSMA eUICC Security Assurance(eSA)及COS SOGIS CC EAL5+两项国际安全认证,成为国内首家在操作系...

关键字: ESIM BSP 操作系统 智能终端

在Linux系统中,动态库(共享库)是程序运行的重要组成部分。当程序需要调用动态库时,系统必须能够找到这些库文件的位置。

关键字: 动态库 Linux

在嵌入式系统开发中,实时操作系统(RTOS)已成为提升效率、简化复杂任务管理的核心工具。随着技术演进,免费开源的RTOS选项日益丰富,为开发者提供了灵活性和成本优势。然而,面对众多选择,如何挑选最适合项目的RTOS?本文...

关键字: RTOS 操作系统

在计算机科学中,文件系统是操作系统最关键的组件之一,它如同数字世界的"图书馆管理员",负责组织、存储和检索海量数据。从智能手机的照片存储到超级计算机的并行计算,文件系统无处不在却又鲜为人知。

关键字: 文件系统 操作系统

ATYM是一个轻量级的运行时,用于在Linux边缘设备(如树莓派)上运行WebAssembly应用程序。ATYM不是在系统上部署大型Docker映像或直接运行本机二进制文件,而是运行小型的沙盒程序,这些程序启动速度快,使...

关键字: 树莓派 ATYM Linux 内存

在计算机网络中,端口映射(Port Forwarding)是一项关键的技术,它允许外部网络通过特定端口访问内部网络中的服务。这种技术广泛应用于家庭网络、企业环境以及云计算场景,是实现远程访问、游戏服务器搭建、FTP共享等...

关键字: Linux Windows

在数字世界的底层,操作系统内核如同城市的基础设施,决定了系统的效率、安全性和扩展性。Linux 内核与 Windows 内核代表了两种截然不同的设计哲学:前者是开源社区的集体智慧结晶,强调灵活性与可定制性;后者是商业公司...

关键字: Linux Windows

北京2025年12月22日 /美通社/ -- 近日,软通动力在自主创新产品发布会上正式发布"软通天鸿操作系统6"。该操作系统由软通动力子公司鸿湖万联基于OpenHarmony社区版深度定制而成,是一款...

关键字: 开源 操作系统 全栈 鸿蒙
关闭