Qt圖形編程基礎(chǔ)之:實驗內(nèi)容——使用Qt編寫“Hello,World”程序
(1)生成一個工程文件(.pro文件)。
使用命令progen產(chǎn)生一個工程文件(progen程序可在tmake的安裝路徑下找到)。
如下所示:
progen–tapp.t–ohello.pro
那樣產(chǎn)生的hello.pro工程文件并不完整,開發(fā)者還需添加工程所包含的頭文件,源文件等信息。
(2)新建一個窗體。
啟動Qt圖形編輯器,使用如下命令:
./designer(該程序在qt-2.3.xforx11的安裝路徑的bin目錄下)
接著單擊編輯器的“new”菜單,彈出了一個“newForm”對話框,在這個對話框里選擇“Widget”,然后單擊“OK”按鈕,這樣就新建了一個窗體。
接下來再對這個窗體的屬性進行設(shè)置,注意把窗體的“name”屬性設(shè)為“Hello”;窗體的各種尺寸設(shè)為寬“240”、高“320”,目的是使窗體大小和FS2410帶的顯示屏的大小一致;窗體背景顏色設(shè)置為白色。具體設(shè)置如圖12.18所示。
圖12.18Hello窗體的屬性設(shè)置
設(shè)置完成后,將其保存為hello.ui文件,這個文件就是Hello窗體的界面存儲文件。
(3)生成Hello窗體類的頭文件和實現(xiàn)文件。
下面根據(jù)上述的界面文件hello.ui使用uic工具產(chǎn)生Hello窗體類的頭文件和實現(xiàn)文件,具體方法是:
$cdqt-2.3.7/bin
$uic–ohello.hhello.ui
$uic–ohello.cpp–implhello.hhello.ui
這樣就得到了Hello窗體類的頭文件hello.h和實現(xiàn)文件hello.cpp。下面就可以根據(jù)需要實現(xiàn)的具體功能,在hello.cpp文件里添加相應(yīng)的代碼。
比如要在Hello的窗體上顯示一個動態(tài)的字符串“Hello,World”,那么需要重新實現(xiàn)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()
{
}
/*以下至結(jié)尾是手動添加的代碼*/
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)編寫主函數(shù)main()。
一個Qt/Embeded應(yīng)用程序應(yīng)該包含一個主函數(shù),主函數(shù)所在的文件名是main.cpp。主函數(shù)是應(yīng)用程序執(zhí)行的入口點。以下是“Hello,World”例子的主函數(shù)文件main.cpp的實現(xiàn)代碼:
/****************************************************************************
**以下是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個文件應(yīng)該被包括在工程文件中,因此還需要編輯hello.pro文件,加入hello.h、hello.cpp、main.cpp這3個文件名。具體定義如下:
/****************************************************************************
**以下是hello.pro文件的內(nèi)容
****************************************************************************/
TEMPLATE=app
CONFIG=qtwarn_onrelease
HEADERS=hello.h
SOURCES=hello.cpp\
main.cpp
INTERFACES=
(6)生成Makefile文件。
編譯器是根據(jù)Makefile文件內(nèi)容來進行編譯的,所以需要生成Makefile文件。Qt提供的tmake工具可以幫助我們從一個工程文件(.pro文件)中產(chǎn)生Makefile文件。結(jié)合當前例子,要從hello.pro生成一個Makefile文件的做法是首先查看環(huán)境變量$TMAKEPATH是否指向ARM編譯器的配置目錄,在命令行下輸入以下命令:
ECHO$TMAKEPATH
如果返回的結(jié)果末尾不是…/qws/linux-arm-g++的字符串,那么需要把環(huán)境變量$TMAKEPATH所指的目錄設(shè)置為指向arm編譯器的配置目錄,過程如下:
EXPORTTMAKEPATH=/TMAKE安裝路徑/QWS/LINUX-ARM-G++
同時,應(yīng)確保當前的QTDIR環(huán)境變量指向Qt/Embedded的安裝路徑,如果不是,則需要執(zhí)行以下過程。
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上運行的可執(zhí)行文件。