Qt图形编程基础之:实验内容——使用Qt编写“Hello,World”程序
扫描二维码
随时随地手机看文章
通过编写一个跳动的“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上运行的可执行文件。