[转]友善之臂2440的qt-embedded2.3.7移植

原文网址:http://blogold.chinaunix.net/u3/109094/showart_2139414.html

arm qt移植全程详解

1概述

1.1   关于QT

Qt是一个跨平台的C++图形用户界面库,由挪威TrollTech公司(www.trolltech.com)出品,它的目的是提供开发应用程序用户界面部分所需要的一切,主要通过汇集C++类的形式来实现这一目的。它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt是完全面向对象的,很容易扩展的,并且允许真正地组件编程的GUI开发工具。

QTEQT Embedded)是它其中的一个版本,适用于嵌入式系统,QTE直接基于Linux中的FrameBuffer设备。

QPEQt Plamtop Environment)是Trolltech公司所推出的针对PDA软件的整体解决方案,包含了从底层的GUI系统、Window ManagerSoft Keyboard到上层的PIM、浏览器、多媒体等方面。目前QPE的高版本已更名为Qtopia,其包含了更多功能。

Qt/Embedded 简介

Qt/Embedded 是一个为嵌入式设备上的图形用户接口和应用开发而订做的C++工具开发包。它通常可以运行在多种不同的处理器上部署的嵌入式Linux操作系统上。居于Qt/Embedded的应用程序可以直接对缓冲帧进行写操作。使用标准的Qt API,我们可以非常熟练的在WindowsUnix编程环境里开发应用程序。本文介绍的QTE基于qt-embedded-2.3.7

1.2   Qtopia介绍

Qtopia Trolltech为采用嵌入式Linux操作系统的消费电子设备而开发的综合应用平台, Qtopia包含完整的应用层、灵活的用户界面、窗口操作系统、应用程序的启动程序以及开发框架。

Trolltech提供三大Qtopia 版本:Qtopia手机版、Qtopia PDA 版和Qtopia 消费电子产品平台,本文介绍的是Qtopia PDA 版,基于qtopia-free-2.2.0版本。

 

1.3   Qt/Embedded 简介

Qt/Embedded 是一个为嵌入式设备上的图形用户接口和应用开发而订做的C++工具开发包。它通常可以运行在多种不同的处理器上部署的嵌入式Linux操作系统上。如果不考虑X Window窗口系统的需要,居于Qt/Embedded的应用程序可以直接对缓冲帧进行写操作。除了类库以外,Qt/Embedded还包括了几个提高开发速度的工具,使用标准的Qt API,我们可以非常熟练的在WindowsUnix编程环境里开发应用程序。


2 QT的安装

2.1开发环境

HOST环境:

系统:Fedora 8

交叉编译工具arm 2.95.3

TARGET环境:

       基于pxa270处理器的CPB6902板卡

       320*240LCD

       内核:Linux-2.6.9

       文件系统:RAMDISK

       软件:

              qt-embeded-2.3.7.tar.gz

              qt-x11-2.3.2.tar.gz

qtopia-free-src-2.2.0.tar.gz 

       e2fsprogs-1.39.tar.gz

       jpegsrc.v6b.tar.gz

       libpng-1.2.14.tar.bz2

       tslib-1.3.tar.bz2

       zlib-1.2.3.tar.bz2

 

2.2 编译步骤

建立编译目录:

mkdir –p /home/work/armqt/qtlibsource

解压以上软件分别得到:

qt-x11tmake-1.13, qt-2.3.7, e2fsprogs-1.39, jpeg-6b, libpng-1.2.14, zlib-1.2.3, tslib-1.3qtopia-free-2.2.0

 

安装顺序:先安装qt-x11-2.3.2,再安装qt-embedded-2.3.7,最后安装qtopia-free-2.2.0

安装qt-x11-2.3.2qt-embedded-2.3.7,需要3个软件安装包:tmake工具安装包,Qt/Embedded安装包,QtX11版的安装包

 

· tmake1.13 或更高版本:生成Qt/Embedded应用工程的Makefile文件。

· Qt/EmbeddedQt/Embedded安装包。

·  Qt 2.3.2 for X11QtX11 版的安装包,产生x11开发环境所需要的两个工具uci,designer

 

1) 编译qt-x11,得到本机运行工具uicdesigner,qvfb

export TMAKEDIR=/home/work/armqt/qtlibsource /tmake-1.13

export TMAKEPATH=/home/work/armqt/qtlibsource//tmake-1.13/lib/linux-g++

 

export QTDIR=/home/work/armqt/qtlibsource/temp/qt-x11

export PATH=$QTDIR/bin:$PATH

export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

 

./configure -no-opengl

make

make -C tools/qvfb

mv tools/qvfb/qvfb bin

 

编译可能遇到的问题:

a)

/home/work/armqt/qtlibsource/qt-x11/include/qvaluestack.h: In member function ‘T QValueStack::pop() [with T = QMap]’:

xml/qxml.cpp:513:   instantiated from here

/home/work/armqt/qtlibsource/qt-x11/include/qvaluestack.h:57: 错误:不能从QValueListIterator > 转换到 const char*’,为实参 1(属于 int remove(const char*))

/home/work/armqt/qtlibsource/qt-x11/include/qvaluestack.h: In member function ‘T QValueStack::pop() [with T = QString]’:

xml/qxml.cpp:2502:   instantiated from here

/home/work/armqt/qtlibsource/qt-x11/include/qvaluestack.h:57: 错误:不能从 QValueListIterator转换到 const char*’,为实参 1(属于 int remove(const char*))

 

解决办法:vi include/qvaluestack.h

57行修正如下:

  remove( this->fromLast() );---àthis->remove( this->fromLast() );

 

 

2) 编译Qt/Embedded 2.3.7

export QTDIR=/home/work/armqt/qtlibsource/temp/qt-2.3.7

export QTEDIR=$QTDIR

export PATH=$QTDIR/bin:$PATH

export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

 

./configure –xplatform linux-arm-g++ -shared  -qvfb -depths 4,8,16,32

make

make install

 

编译遇到的问题:

a)

/home/work/armqt/qtlibsource/temp/qt-2.3.7/include/qsortedlist.h:51: 错误:‘clear 的实参不依赖模板参数,所以 clear 的声明必须可用

/home/work/armqt/qtlibsource/temp/qt-2.3.7/include/qsortedlist.h:51: 错误:(如果您使用 -fpermissive’,G++会接受您的代码,但是允许使用未定义的名称是过时的风格)

解决方法:

vi include/qsortedlist.h

51行修正如下:

~QSortedList() { clear(); }--à~QSortedList() { this->clear(); }

 

 

b)

/home/work/armqt/qtlibsource/temp/qt-2.3.7/include/qwindowsystem_qws.h:229: 错误:‘QWSInputMethod未声明

解决发法:

vi include/qwindowsystem_qws.h

227增加:

#ifndef QT_NO_QWS_IM

    static void setCurrentInputMethod( QWSInputMethod *im );

---à

#ifndef QT_NO_QWS_IM

    class QWSInputMethod;

    static void setCurrentInputMethod( QWSInputMethod *im );

 

c)

kernel/qgfxvfb_qws.cpp:143: 错误:‘is_screen_gfx 在此作用域中尚未声明

kernel/qgfxvfb_qws.cpp:144: 错误:‘xoffs 在此作用域中尚未声明

kernel/qgfxvfb_qws.cpp:144: 错误:‘yoffs 在此作用域中尚未声明

……..

kernel/qgfxtransformed_qws.cpp:674: 错误:‘xoffs 在此作用域中尚未声明

kernel/qgfxtransformed_qws.cpp:674: 错误:‘yoffs 在此作用域中尚未声明

……

解决办法:

修改相应文件,在所有未声明变量前加this->

 

 

3)编译qtopia-free-2.2.0

建立目录include,lib, 这两个目录是存放编译后的库与头文件,为后面交叉编译用)

mkdir –p /home/work/armqt/lib

mkdir –p /home/work/armqt/include

编译相关库

(1) e2fs:

cd home/work/armqt/qtlibsource/e2fsprogs-1.39

./configure --host=arm-linux

--enable-elf-shlibs --with-cc=arm-linux-gcc

--with-linker=arm-linux-ld --prefix=/usr/local/arm/2.95.3/arm-linux  

 

make

make install

cp lib/libuuid.so* ../lib

 

(2) jpeg-6b

cd /home/work/armqt/qtlibsource/jpeg-6b

./configure -enable-shared

vi Makefile

修改:

CC= arm-linux-gcc

AR= arm-linux-ar rc

AR2=arm-linux-ranlib

 

make

make install

 

cp *.h ../include/

cp libjpeg.a ../lib/

 

(3) zlib-1.2.3

cd /home/work/armqt/qtlibsource/zlib-1.2.3

./configure -shared

Vi Makefile

 

CC=arm-linux-gcc

LDSHARED=arm-linux-gcc -shared -Wl,-soname,libz.so.1

CPP=arm-linux-gcc -E

AR=arm-linux-ar rc

RANLIB=arm-linux-ranlib

SHELL=/bin/sh

EXE=

 

prefix =/usr/local/arm/2.95.3/arm-linux

 

make

make install

cp libz.so* ../lib/

cp *.h ../include/

 

(4) libpng-1.2.14

cp scripts/makefile.linux  ./Makefile  

vi Makefile

 

AR_RC=arm-linux-ar rc

CC=arm-linux-gcc

RANLIB=arm-linux-ranlib

prefix=/usr/local/arm/2.95.3/arm-linux

 

make

make install

cp libpng12.so*  ../lib/

cp libpng12.so ../lib/libpng.so

cp *.h ../include/

 

(5) tslib-1.3 (在我们的开发平台上由于还没有触摸屏驱动,使用的是usb鼠标,所以暂时没有使用此库,后面不再叙述关于触摸屏的相关内容)

cd /home/work/armqt/qtlibsource/tslib-1.3

./autogen.sh

echo"ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache

./configure --host=arm-linux--cache-file=arm-linux.cache

 --enable-inputapi=no --srcdir=/home/qtopia-arm-home/arm/tslib

make

make install

cp src/.libs/libts-0.0.so.0* ../lib/

cp src/.libs/libts.so ../lib/

cp src/*.h ../include/

 

 

6)编译Qtopia

cd /home/work/armqt/ qtlibsource /qtopia-free-2.2.0

 

(a)修改相关文件:

vi /home/work/armqt/qtlibsource/qtopia-free-2.2.0/qtopia/mkspecs/qws/

linux-arm-g++/qmake.conf

QMAKE_LIBS_QT = -lqte

修改为:

QMAKE_LIBS_QT           = -lqte -lpng -lz -luuid -ljpeg

 

让Qtopia支持鼠标,修改文件:

vi home/work/armqt/qtlibsource/qtopia-free-2.2.0/qtopia /src/qt/qconfig-qpe.h

注释如下宏:

/*

#ifndef QT_NO_QWS_CURSOR

#define QT_NO_QWS_CURSOR

#endif

#ifndef QT_NO_QWS_MOUSE_AUTO

#define QT_NO_QWS_MOUSE_AUTO

#endif

#ifndef QT_NO_QWS_MOUSE_PC

#define QT_NO_QWS_MOUSE_PC

#endif

*/

 

(b)设置环境变量:

export QTDIR=/home/work/armqt/qtlibsource/qtopia-free-2.2.0/qt2

export QPEDIR=/home/work/armqt/ qtlibsource/qtopia-free-2.2.0/qtopia

export LD_LIBRARY_PATH=$QTDIR/lib:$QPEDIR/lib:$LD_LIBRARY_PATH

export TMAKEDIR=/home/work/armqt/qtlibsource/qtopia-free-2.2.0/tmake

export TMAKEPATH=$TMAKEDIR/lib/qws/linux-arm-g++

 

(c)准备配置文件:

cp $QPEDIR/src/qt/qconfig-qpe.h $QTDIR/src/tools

cd $QPEDIR/src/libraries/qtopia

cp custom-linux-ipaq-g++.cpp custom-linux-arm-g++.cpp

cp custom-linux-ipaq-g++.h custom-linux-arm-g++.h

 

(d)生成Makefile文件

./configure -qte "-embedded -xplatform linux-arm-g++ -qconfig qpe

-no-qvfb -depths 8,16,24,32  -no-xft -system-jpeg  -system-libpng

-system-zlib -gif -thread -release -I/home/work/armqt/include

-L/home/work/armqt/lib -lpng -lz -luuid -ljpeg" -qpe  '-xplatform

linux-arm-g++ -edition pda -displaysize 640x480

 -I/home/work/armqt/include -L/home/work/armqt/lib

-prefix=/home/work/qtopia'

 

 

make

make install

最后在/home/work/目录下生成了一个文件夹为qtopia的Qt文件系统

 

 

编译过程出现的问题

1)

……/qtopia-free-2.2.0/qt2/include/qvaluestack.h:57:错误:不能从               QValueListIterator >                转换到                const char*,为实参                1(属于                int remove(const char*))

解决方法:

vi qt2/include/qvaluestack.h

第57行

remove( this->fromLast() );-à this->remove(this->fromLast() );

 

 

2)

../../libraries/qtopia/qdawg.cpp:294: 错误:有多余的限定                QDawgPrivate::                在成员                QDawgPrivate                上

make[6]: *** [.obj/release-shared/qdawg.o] 错误 1

make[5]: *** [all] 错误 2

make[4]: *** [sub-tools-qdawggen] 错误 2

make[3]: *** [sub-src-components_pro] 错误 2

make[2]: *** [all] 错误 2

make[1]: *** [all] 错误 2

解决办法:

vi qtopia/src/libraries/qtopia/qdawg.cpp

第294行:

  QDawgPrivate::~QDawgPrivate()-à ~QDawgPrivate()

 

 

(e)拷贝相关库

将前面准备工作编译的相关库文件考入到Qt文件系统中

cp /home/work/armqt/lib/*  /home/work/qtopia/lib

 

 

(7)在开发板上运行

由于我们的根文件系统只有4M,无法容纳生成的Qt文件系统,所以这里采用NFS的方式来运行。

主机Qtopia文件系统路径如下:

/home/project/pxa270/rootfs/qtopia

我们将qtopia挂载到开发板的/mnt/gui目录下:

mkdir /mnt/gui

mount -t nfs -o intr,nolock,rsize=1024,wsize=1024

192.168.0.170:/home/project/pxa270/rootfs /mnt/gui

(如果不加入rsize、wsize参数会出现nfs 没有响应的问题)

 

在qtopia下可能没有pointercal文件,如果没有可能会导致只能看到qt的初始界面,出现一个对话框:calibration  can only be performed on a touch screen

点击始终无法进入qt。

可以在/etc目录下创建一个内容为 1 0 1 0 1 1  65536的pointercal文件解决。

 

消除Warning: Unable to open /usr/share/zoneinfo/zone.tab

在目标机上建立目录mkdir –p /usr/share/zoneinfo

拷贝主机目录文件/qtopia-free-2.2.0/qtopia/etc/zoneinfo/zone.tab到目标机/usr/share/zoneinfo下(利用NFS拷贝):

 

设置板子上QT的运行环境变量:

export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/gui/qtopia/bin

export LD_LIBRARY_PATH=/lib:/usr/lib:/mnt/gui/qtopia/lib

export LANG="zh"_CN

export QWS_MOUSE_PROTO="USB:/dev/input/mice"(指定鼠标为输入设备)

export QTDIR="/mnt/gui/qtopia"

export QPEDIR="/mnt/gui/qtopia"

 

运行:

cd /mnt/gui/qtopia/bin

./qpe

就可以看到漂亮的qtopia界面了。

 

3 QT程序编写与中文化

前面我们在主机上编译安装了Qt/Embeded工具开发包,现在就可以利用此开发包进行QT程序的编写了,下面以编写一个Hello,QT/Embeded为例来演示如何开发并在发布一个QT应用程序。

3.1程序的编写

一个应用通常对应一个工程文件,生成一个工程文件,并对它做一些简单的编辑,然后

使用一个专门的工具(例如 tmake)处理这个工程文件,就可以生成一个 Makefile文件。

 产生一个工程文件的其中一个方法是使用 progen 命令(progen 程序可在tmake 的安装路径下找到) 下面使用progen 产生一个名为 hello 的工程文件

 

/etc/profile中加入相关工具的路径信息:

pathmunge /home/work/armqt/qtlibsource/tmake-1.13/bin

pathmunge /home/work/armqt/qtlibsource/qt-2.3.7/bin (包含progen工具)

pathmunge /home/work/armqt/qtopia-free-2.2.0/dqt/bin(包含lupdatelinguistlrelease工具)

pathmunge /home/work/armqt/qtlibsource/qt-x11/bin (包含designer工具)

 

1.生成hello.pro工程文件:

progen –t app.t –o hello.pro

 

2编写一个hello.cpp

#include

#include

#include

#include

 

int main( int argc, char **argv )

{

    QApplication app( argc, argv );

    QPushButton hello( QPushButton::tr("Hello,world!"), 0 );

    hello.setGeometry( 20, 20, 180, 100 );

    app.setMainWidget( &hello );

    hello.show();

    return app.exec();

}

 

3.在.pro文件中加入hello.cpp

TEMPLATE  = app

CONFIG    = qt warn_on release

HEADERS   =

SOURCES   = hello.cpp  

INTERFACES  =

 

4.生成Makefile文件

配置环境变量

export $TMAKPATH= /home/work/armqt/qtlibsource/tmake-1.13/lib/qws/linux-arm-g++

export $QTDIR=/home/work/armqt/qtlibsource/qt-2.3.7

tmake -o Makefile hello.pro

 

修改Makefile

1):LINK    =       arm-linux-g++

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

 

make

就可以生成一个交叉编译环境的可执行文件hello了。

 

3.2添加一个QT/Embeded应用到Qtopia

1.建立应用启动器(.desktop文件)

在板子上的目录/mnt/gui/qtopia/apps/Applications 建立一个hello.desktop文件,添加如下内容:

[Translation]

File=QtopiaApplications

Context=Hello

[Desktop Entry]

Comment[]=A Hello Program

Exec=hello

Icon=hello

Type=Application

Name[]=Hello

这些内容指明了应用的名称,图标等信息。

 

2.添加hello应用程序的图标

/mnt/gui/qtopia/pics/目录下:

mkdir hello

添加我们喜欢的应用程序图标到此目录(利用NFS拷贝)

hello.png

 

2)  拷贝前面交叉编译好的可执行文件hello到如下目录(利用NFS拷贝):

/mnt/gui/qtopia/bin

 

 

然后在开发板上运行qtopia

./qpe

进入到Application界面,我们就可以看到一个图标为hello的应用程序,点击该程序,就可以看到我们的第一个Hello,world应用程序了。


3.3开发QT中文程序

这里我们以开发一个中文显示的QT下拉菜单程序,中文的显示我们是利用在程序中需要汉化的地方用tr()方法标识,然后利用lupdate,lreleaselingust工具,生成.ts.qmi18n需要的文件;这三个工具我们可以在/home/work/armqt/qtopia-free-2.2.0/dqt/bin中找到。

 

QT中文程序的制作步骤如下:

1)编写并编译应用程序

2)在.pro文件中加入TRANSLATIONS    = XXX_CN.ts

3lupdate 利用.pro文件生成相应的.ts文件(此文件为一个xml文件,含有我们需要翻译的源文字)

4)用lingust对生成的.ts文件进行翻译

5)利用lrelease 结合.ts文件生成.qm文件

6)发布可执行文件和.qm文件。

 

1.       编写下拉菜单程序

 

mainwidget.h

 

#include

#include

#include

#include

#include

#include

 

class MyMainWidget: public QMainWindow

{

                Q_OBJECT

public:

                MyMainWidget( QWidget *parent=0, const char *name=0 );

public slots:

                void newFile();

                void openFile();

                void saveFile();

                void exitMain();

                void copyFile();

private:

                QLabel *statuslabel;

};

 

#endif

 

 

 

//如下(加粗)可以看到在我们需要汉化的地方都用tr()方法进行标识,利用lupdate就可提取出其中需要汉化的源文字,从而生成.ts文件。

mainwidget.cpp

 

#include "mainwidget.h"

MyMainWidget::MyMainWidget( QWidget *parent, const char *name )

                        :QMainWindow( parent, name )

{

                setCaption(MyMainWidget::tr("chinese qt Example"));

                setBackgroundColor( white );

                statuslabel = new QLabel( "", this );

                statuslabel->setGeometry( 50, 50, 250, 50 );

                statuslabel->setBackgroundColor( white );

 

                QPopupMenu *filemenu1 = new QPopupMenu;

               filemenu1->insertItem(QPopupMenu::tr("&New"), this, SLOT( newFile() ),CTRL+Key_N );

                filemenu1->insertItem(QPopupMenu::tr("&Open"), this, SLOT( openFile() ),CTRL+Key_O );

                filemenu1->insertItem(QPopupMenu::tr("&Save"), this, SLOT( saveFile() ), CTRL+Key_S );

                filemenu1->insertSeparator();

                filemenu1->insertItem(QPopupMenu::tr("E&xit"), this, SLOT( exitMain() ),CTRL+Key_X );

                QPopupMenu *filemenu2 = new QPopupMenu;

                filemenu2->insertItem(QPopupMenu::tr("&Copy"), this, SLOT( copyFile() ),CTRL+Key_C );

                QMenuBar *menubar;

                menubar = new QMenuBar( this );

                menubar->insertItem(QMenuBar::tr("&File"), filemenu1);

                menubar->insertItem(QMenuBar::tr("&Edit"), filemenu2);

                statusBar()->message( MyMainWidget::tr("Ready"));

}

 

void MyMainWidget::newFile()

{

                statuslabel->setText( MyMainWidget::tr("File has been created!") );

                statusBar()->clear();

                statusBar()->message( MyMainWidget::tr("created") );

}

 

void MyMainWidget::openFile()

{

                statuslabel->setText( MyMainWidget::tr("File has been opened!") );

                statusBar()->clear();

                statusBar()->message( MyMainWidget::tr("Opened") );

}

 

void MyMainWidget::saveFile()

{

                statuslabel->setText( MyMainWidget::tr("File has been saved!") );

                statusBar()->clear();

                statusBar()->message( MyMainWidget::tr("Saved") );

}

 

void MyMainWidget::exitMain()

{

                QApplication::exit();

}

 

void MyMainWidget::copyFile()

{

                statuslabel->setText( MyMainWidget::tr("File has been copyed!") );

                statusBar()->clear();

                statusBar()->message( MyMainWidget::tr("copyed") );

}

 

 

 

main.cpp

#include

#include "mainwidget.h"

 

int main(int argc, char **argv)

{

        QApplication app(argc,argv);

        app.setFont(QFont("unifont",16,50));

        QTranslator translator( 0 );

        translator.load( QString("hello_CN.qm"),".");

        app.installTranslator( &translator );

        MyMainWidget *mymainwidget = new MyMainWidget(0);

        mymainwidget->setGeometry(10,30,280,200);

        app.setMainWidget(mymainwidget);

        mymainwidget->show();

        return app.exec();

 

}

 

2.       生成mymain.pro工程文件

progen –t app.t –o mymain.pro

修改mymain.pro

 

TEMPLATE        = app

CONFIG          = qt warn_on release

HEADERS         = mainwidget.h

SOURCES         = mainwidget.cpp main.cpp

INTERFACES      =

TRANSLATIONS    = mymain_CN.ts

 

3.       生成mymain_CN.ts

lupdate mymain.pro

 

4. 翻译my_CN.ts中提取的源文字。


生成.qm文件

lrelease  my_CN.ts

root@localhost hellotest]# ls

mymain        mymain_CN.ts  mymain.pro  main.o          mainwidget.h  Makefile            moc_mainwidget.o mymain_CN.qm    main.cpp   mainwidget.cpp  mainwidget.o  moc_mainwidget.cpp

 

那么程序是如何找到这个源文字对应的译文呢?

可以看到在main.cpp中如下代码:

int main(int argc, char **argv)

{

        ……

        app.setFont(QFont("unifont",16,50));

        QTranslator translator( 0 );

        translator.load( QString("mymain_CN.qm"),".");

        app.installTranslator( &translator );

      ……

 

}

这里我们使用了qtopia中自带的一种字体unifont,如何想要qt支持更加丰富的字体,我们可以自己添加字库。

 

按照3.3章节中的方法添加mymain到应用到Qtopia中,记得需要将mymain_CN.qm文件一起放到/mnt/gui/qtopia/bin文件夹下。

 

运行./qpe

点击mymain应用程序,就可以看到中文的下拉工具菜单了。

注意:如果你设置的字体QFont("unifont",16,50)中有一个参数不正确就会导致显示出方块。

7制作中文字库

程序是如何去寻找需要的字库呢?

我们可以在QT文件系统目录下:/mnt/gui/qtopia/lib/fonts中找到qt自带的字库文件,

cd /mnt/gui/qtopia/lib/fonts

ls

unifont.bdf  unifont_160_50_t5.qpf

helvetica_100_50.qpf        helvetica_240_75_t15.qpf

helvetica_100_50_t10.qpf    helvetica_240_75_t5.qpf

……

 

同时该目录下还有一个fontdir文件:

vi fontdir

……

helvetica helvR18.bdf BDF n 50 180 u

helvetica helvR24.bdf BDF n 50 240 u

# Unifont is available in source form from http://czyborra.com/unifont/

unifont unifont.bdf BDF n 50 160 u

babelfish babelfish.ttf FT n 50 0 s

smallsmooth verdana.ttf FT n 50 0 s 90

……

每一行是关于一种字体的设置,对应列的定义如下:

<字体名称> <字体文件名> <字体渲染类型> <是否斜体> <是否粗体> <尺寸> <字体标志> [尺寸列表]

其中,

<字体渲染类型>:可以为TTFBDFQPF三种类型;

<是否斜体>y表示为斜体,n表示正常体;

<是否粗体>50表示正常体,75表示粗体;

<标志>a使用ASCII字符集,u使用unicode字符集,s使用锯齿平滑(anti-aliased)

<尺寸>0,则系统从[尺寸列表]中提取可以转换的字体尺寸;

 

我们上面的中文下拉菜单程序就是利用qt自带的一种中文字体unifont,程序会读取/mnt/gui/qtopia/lib/fonts/fontdir文件,并匹配相应的字体,如果在程序中QFont("unifont",16,50)中参数设置不正确,就无法匹配到相关字体,所以自然就显示出了方块了。(同时字体标志一定要加上u,说明使用unicode字符集,否则也会出现方块)

 

知道如何读取中文字库文件,我们就可以制作自己喜欢的中文字库并显示了。


你可能感兴趣的:(QT)