Tag: C/C++

小宁和你聊编程之四: 语句篇

Posted by – September 26, 2017

上一篇《小宁和你聊编程之三: 类型篇》,我们主要和大家聊了聊什么是变量的类型。大家还有印象么?什么是类型,我们将它应用在什么地方?我们又是如何在编程实践中使用它的呢? 你有什么想法需要和我交流么?你遇到了什么困难么?有什么我可以帮助你的?

让我们再次回顾下类型的内容,一起来复习一下:
什么是类型:

类型就是变量的一个分类(归类)。

比如我们把红富士、黄元帅都叫做苹果, 我们把海南香蕉、进口香蕉都要叫香蕉.
我们把和田大枣、西安洋县枣都叫大枣. 或者我们把男孩子,女孩子都叫孩子。
这是对TA们的一个分类。在编程中这个分类就是其类型。
我们也举例进行了说明。比如:

int iFive = 5; //int(整型)变量iFive的值为5.
string strJ="jin"; //字符串strJ的值为"jin"

我们前三节说明了编程的本质 、编程的核心概念: 变量编程的核心概念:类型 . 那么变量和类型他们是如何组合起来发挥作用的呢?
我们今天来看编程的另一个核心概念: 语句

那么什么是语句呢?其它我们早就见过它了。
1.什么是语句?


简单来说, 语句就是表达完整意思的一句话。

这里面有两个要点:
.表达完整意思: 就像你说话得说完整,要不然大家会听不明白。
比如你说,我现在要… 如果你这么说,大家就在等着你说完,要不不知道你要做什么。编程也是一样。
生活中我们是为了交流,沟通,编写代码时,则是为了清楚地告诉计算机我们想让它做什么。

.一句话: 这句话通常以;(绝大多数情况) 或者右大括号}, 或者>, 或者以) 结束.
现实中,我们说话的时候,说完了会有一个句号,或者一个省略号,或者一到多个!, 或者?号等等。
总之大家知道这句话结束了。那么在编程中,好多程序都有语句结束标志。
比如C++中,绝大多数情况下以;或者}为语句结束的标志。

2.语句的应用?(举个例子)


那么语句在编程中是如何使用的呢?其实它和变量、类型一样,随处可见,应用及其广泛.
基本可以说是变量和类型组成了语句。比如:

int i23=23; //语句,以int开始, 以;结束.
int iSix=6; //一条语句,以int始, 以;终.

再如:

string strJ="j"; //语句:以string始,以;终
string strJor="Mi"; //语句:以string开始,以;终

又如:

char cCh='c'; //语句:以char始,以;终.
char * pHi="Hi"; //语句:以chra始,以;终.

最后来个空语句:

; //以;结束的语句。什么也不做.

3.语句的实践?


我们上面和大家举例说明了语句在程序中的应用, 那现在来实践一下.写段代码来使用它们。
请打开VS2013或者打开http://cpp.sh来写上如下代码:

#include <iostream> //一条语句, 以>结束
#include <string> //一条语句
using namespace std; //一条语句
int main()  //以)结束
{
    int i23 = 23; // 一条完整的语句
    int iSix = 6; // 

    float fFivePotFive = 5.5; // 一条完整的语句。告诉计算机保存变量的值为5.5
    float fNine = 9;        // 

    string strJin = "jin"; // 告诉计算机, 在strJin中保存"jin"这个字符串。
    string strJordan = "Michael Jordan"; //

    char cChar = 'c';  //告诉计算机在cChar中保存字符'c'
    char * pHello = "Hello"; //

    std::cout << i23 << "," << iSix << std::endl; 
    //一条语句:打印出 i23的值, 一个,号, 和iSix的值,并且换行
    std::cout << fFivePotFive << "," << fNine << std::endl;
    //一条语句:打印出strJin的值,一个逗号, strJordan的值,然后换行
    std::cout << strJin << "," << strJordan << std::endl;
    std::cout << cChar << "," << pHello << std::endl;
    return 0;
}

如果使用的是VS2013, 那么我们按F7, 如果没有错误的话, 就会编译生成我们的程序,并且会有下面的输出:
vs2013语句: 程序输出

如果使用http://cpp.sh也会产生下面的输出.
cpp.sh语句: 程序输出

这样我们就定义了很多条“语句”, 程序就是由很多条语句组成完整的意思.就像我们说了好多句话,表达了我们的想法。然后我们看到了程序运行后输出的结果.

恭喜你, 今天你和我一起学习了又一基本概念: 语句
编程核心概念之四: 语句 
语句:

语句是表达完整意思的一句话。

语句的应用
语句的实践

怎么样?有没有理解语句的概念?你是如何理解C++中语句的概念的?能不能举几个例子?

请大家多多动手,让编程也成为你的一种爱好和生产力。
戳右上角 小宁静致远 或扫码关注我, 欢迎、感激传播! ^_^
期待和你多交流、共成长。谢谢!
扫描关注小宁静致远

鼓励我的创作?
您的鼓励我的动力!

Qt事件

Posted by – May 18, 2010

Qt事件:

Refers to:
http://www.w3china.org/blog/more.asp?name=oceanblue&id=41941

Qt程序是事件驱动的, 程序的每个动作都是由幕后某个事件所触发. Qt事件的类型很多, 常见的qt的事件如下:
键盘事件: 按键按下和松开.
鼠标事件: 鼠标移动,鼠标按键的按下和松开.
拖放事件: 用鼠标进行拖放.
滚轮事件: 鼠标滚轮滚动.
绘屏事件: 重绘屏幕的某些部分.
定时事件: 定时器到时.
焦点事件: 键盘焦点移动.
进入和离开事件: 鼠标移入widget之内,或是移出.
移动事件: widget的位置改变.
大小改变事件: widget的大小改变.
显示和隐藏事件: widget显示和隐藏.
窗口事件: 窗口是否为当前窗口.

还有一些非常见的qt事件,比如socket事件,剪贴板事件,字体改变,布局改变等等.

Qt 的事件和Qt中的signal不一样. 后者通常用来”使用”widget, 而前者用来”实现” widget. 比如一个按钮, 我们使用这个按钮的时候, 我们只关心他clicked()的signal, 至于这个按钮如何接收处理鼠标事件,再发射这个信号,我们是不用关心的. 但是如果我们要重载一个按钮的时候,我们就要面对event了. 比如我们可以改变它的行为,在鼠标按键按下的时候(mouse press event) 就触发clicked()的signal而不是通常在释放的( mouse release event)时候.

2. 事件产生和处理流程

2.1 事件的产生
事件的两种来源:

一种是系统产生的;通常是window system把从系统得到的消息,比如鼠标按键,键盘按键等, 放入系统的消息队列中. Qt事件循环的时候读取这些事件,转化为QEvent,再依次处理.

一种是由Qt应用程序程序自身产生的.程序产生事件有两种方式, 一种是调用QApplication::postEvent(). 例如QWidget::update()函数,当需要重新绘制屏幕时,程序调用update()函数,new出来一个paintEvent,调用 QApplication::postEvent(),将其放入Qt的消息队列中,等待依次被处理. 另一种方式是调用sendEvent()函数. 这时候事件不会放入队列, 而是直接被派发和处理, QWidget::repaint()函数用的就是这种方式.

// 自定义事件的时候讲述: 需要注意的时, 这两个函数的使用方法不大一样, 一个是new, 一个是….

2.2 事件的调度
两种调度方式,一种是同步的, 一种是异步.

Qt的事件循环是异步的,当调用QApplication::exec()时,就进入了事件循环. 该循环可以简化的描述为如下的代码:

while ( !app_exit_loop )
{
while( !postedEvents ) { processPostedEvents() }
while( !qwsEvnts ){ qwsProcessEvents();   }
while( !postedEvents ) { processPostedEvents() }

}

先处理Qt事件队列中的事件, 直至为空. 再处理系统消息队列中的消息, 直至为空, 在处理系统消息的时候会产生新的Qt事件, 需要对其再次进行处理.

调用QApplication::sendEvent的时候, 消息会立即被处理,是同步的. 实际上QApplication::sendEvent()是通过调用QApplication::notify(), 直接进入了事件的派发和处理环节.

2.3 事件的派发和处理
首先说明Qt中事件过滤器的概念. 事件过滤器是Qt中一个独特的事件处理机制, 功能强大而且使用起来灵活方便. 通过它, 可以让一个对象侦听拦截另外一个对象的事件. 事件过滤器是这样实现的: 在所有Qt对象的基类: QObject中有一个类型为QObjectList的成员变量,名字为eventFilters,当某个QObjec (qobjA)给另一个QObject (qobjB)安装了事件过滤器之后, qobjB会把qobjA的指针保存在eventFilters中. 在qobjB处理事件之前,会先去检查eventFilters列表, 如果非空, 就先调用列表中对象的eventFilter()函数. 一个对象可以给多个对象安装过滤器. 同样, 一个对象能同时被安装多个过滤器, 在事件到达之后, 这些过滤器以安装次序的反序被调用. 事件过滤器函数( eventFilter() ) 返回值是bool型, 如果返回true, 则表示该事件已经被处理完毕, Qt将直接返回, 进行下一事件的处理; 如果返回false, 事件将接着被送往剩下的事件过滤器或是目标对象进行处理.

Qt中,事件的派发是从 QApplication::notify() 开始的, 因为QAppliction也是继承自QObject, 所以先检查QAppliation对象, 如果有事件过滤器安装在qApp上, 先调用这些事件过滤器. 接下来QApplication::notify() 会过滤或合并一些事件(比如失效widget的鼠标事件会被过滤掉, 而同一区域重复的绘图事件会被合并). 之后,事件被送到reciver::event() 处理.

同样, 在reciver::event()中, 先检查有无事件过滤器安装在reciever上. 若有, 则调用之. 接下来,根据QEvent的类型, 调用相应的特定事件处理函数. 一些常见的事件都有特定事件处理函数, 比如:mousePressEvent(), focusOutEvent(), resizeEvent(), paintEvent(), resizeEvent()等等. 在实际应用中, 经常需要重载这些特定事件处理函数在处理事件. 但对于那些不常见的事件, 是没有相对应的特定事件处理函数的. 如果要处理这些事件, 就需要使用别的办法, 比如重载event() 函数, 或是安装事件过滤器.

事件派发和处理的流程图如下:

2.4 事件的转发

对于某些类别的事件, 如果在整个事件的派发过程结束后还没有被处理, 那么这个事件将会向上转发给它的父widget, 直到最顶层窗口. 如图所示, 事件最先发送给QCheckBox, 如果QCheckBox没有处理, 那么由QGroupBox接着处理, 如果QGroupBox没有处理, 再送到QDialog, 因为QDialog已经是最顶层widget, 所以如果QDialog不处理, QEvent将停止转发.       如何判断一个事件是否被处理了呢? Qt中和事件相关的函数通过两种方式相互通信. QApplication::notify(), QObject::eventFilter(), QObject::event() 通过返回bool值来表示是否已处理. “真”表示已经处理, “假”表示事件需要继续传递. 另一种是调用QEvent::ignore() 或 QEvent::accept() 对事件进行标识. 这种方式只用于event() 函数和特定事件处理函数之间的沟通. 而且只有用在某些类别事件上是有意义的, 这些事件就是上面提到的那些会被转发的事件, 包括: 鼠标, 滚轮, 按键等事件.
3. 实际运用

根据对Qt事件机制的分析, 我们可以得到5种级别的事件过滤,处理办法. 以功能从弱到强, 排列如下:

3.1 重载特定事件处理函数.
最常见的事件处理办法就是重载象mousePressEvent(), keyPressEvent(), paintEvent() 这样的特定事件处理函数. 以按键事件为例, 一个典型的处理函数如下:

void imageView::keyPressEvent(QKeyEvent * event)
{
switch (event->key()) {
case Key_Plus:
zoomIn();
break;
case Key_Minus:
zoomOut();
break;
case Key_Left:
// …
default:
QWidget::keyPressEvent(event);
}
}

3.2重载event()函数.
通过重载event()函数,我们可以在事件被特定的事件处理函数处理之前(象keyPressEvent())处理它. 比如, 当我们想改变tab键的默认动作时,一般要重载这个函数. 在处理一些不常见的事件(比如:LayoutDirectionChange)时,evnet()也很有用,因为这些函数没有相应的特定事件处理函数. 当我们重载event()函数时, 需要调用父类的event()函数来处理我们不需要处理或是不清楚如何处理的事件.

下面这个例子演示了如何重载event()函数, 改变Tab键的默认动作: (默认的是键盘焦点移动到下一个控件上. )

bool CodeEditor::event(QEvent * event)
{
if (event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = (QKeyEvent *) event;
if (keyEvent->key() == Key_Tab)
{
insertAtCurrentPosition(‘\t’);
return true;
}
}
return QWidget::event(event);
}

3.3 在Qt对象上安装事件过滤器.

安装事件过滤器有两个步骤: (假设要用A来监视过滤B的事件)
首先调用B的installEventFilter( const QOject *obj ), 以A的指针作为参数. 这样所有发往B的事件都将先由A的eventFilter()处理.
然后, A要重载QObject::eventFilter()函数, 在eventFilter() 中书写对事件进行处理的代码.
用这种方法改写上面的例子: (假设我们将CodeEditor 放在MainWidget中)

MainWidget::MainWidget()
{
CodeEditor * ce = new CodeEditor( this, “code editor”);
ce->installEventFilter( this );
}

bool MainWidget::eventFilter( QOject * target , QEvent * event )
{
if( target == ce )
{
if( event->type() == QEvent::KeyPress )
{
QKeyEvent *ke = (QKeyEvent *) event;
if( ke->key() == Key_Tab )
{
ce->insertAtCurrentPosition(‘\t’);
return true;
}
}
}
return false;
}

3.4 给QAppliction对象安装事件过滤器.
一旦我们给qApp(每个程序中唯一的QApplication对象)装上过滤器,那么所有的事件在发往任何其他的过滤器时,都要先经过当前这个 eventFilter(). 在debug的时候,这个办法就非常有用, 也常常被用来处理失效了的widget的鼠标事件,通常这些事件会被QApplication::notify()丢掉. ( 在QApplication::notify() 中, 是先调用qApp的过滤器, 再对事件进行分析, 以决定是否合并或丢弃)

3.5 继承QApplication类,并重载notify()函数.

Qt是用QApplication::notify()函数来分发事件的.想要在任何事件过滤器查看任何事件之前先得到这些事件,重载这个函数是唯一的办法. 通常来说事件过滤器更好用一些, 因为不需要去继承QApplication类. 而且可以给QApplication对象安装任意个数的事件过滤器, 相比之下, notify()函数只有一个.

Calling Qt Functions From Unix Signal Handlers

Posted by – May 18, 2010

Home · All Classes · All Functions · Overviews

Calling Qt Functions From Unix Signal Handlers

Refers to:
http://doc.qt.nokia.com/4.6/unix-signals.html
http://www.opengroup.org/onlinepubs/000095399/functions/xsh_chap02_04.html#tag_02_04_01
http://doc.qt.nokia.com/4.6/qsocketnotifier.html
http://doc.qt.nokia.com/4.6/platform-specific.html
You can’t call Qt functions from Unix signal handlers. The standard POSIX rule applies: You can only call async-signal-safe functions from signal handlers. See Signal Actions for the complete list of functions you can call from Unix signal handlers.

But don’t despair, there is a way to use Unix signal handlers with Qt. The strategy is to have your Unix signal handler do something that will eventually cause a Qt signal to be emitted, and then you simply return from your Unix signal handler. Back in your Qt program, that Qt signal gets emitted and then received by your Qt slot function, where you can safely do whatever Qt stuff you weren’t allowed to do in the Unix signal handler.

One simple way to make this happen is to declare a socket pair in your class for each Unix signal you want to handle. The socket pairs are declared as static data members. You also create a QSocketNotifier to monitor the read end of each socket pair, declare your Unix signal handlers to be static class methods, and declare a slot function corresponding to each of your Unix signal handlers. In this example, we intend to handle both the SIGHUP and SIGTERM signals. Note: You should read the socketpair(2) and the sigaction(2) man pages before plowing through the following code snippets.

[cpp]
class MyDaemon : public QObject
{
Q_OBJECT

public:
MyDaemon(QObject *parent = 0, const char *name = 0);
~MyDaemon();

// Unix signal handlers.
static void hupSignalHandler(int unused);
static void termSignalHandler(int unused);

public slots:
// Qt signal handlers.
void handleSigHup();
void handleSigTerm();

private:
static int sighupFd[2];
static int sigtermFd[2];

QSocketNotifier *snHup;
QSocketNotifier *snTerm;
};
[/cpp]

In the MyDaemon constructor, use the socketpair(2) function to initialize each file descriptor pair, and then create the QSocketNotifier to monitor the read end of each pair. The activated() signal of each QSocketNotifier is connected to the appropriate slot function, which effectively converts the Unix signal to the QSocketNotifier::activated() signal.

[cpp]
MyDaemon::MyDaemon(QObject *parent, const char *name)
: QObject(parent,name)
{
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd))
qFatal("Couldn’t create HUP socketpair");

if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd))
qFatal("Couldn’t create TERM socketpair");
snHup = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
snTerm = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this);
connect(snTerm, SIGNAL(activated(int)), this, SLOT(handleSigTerm()));


}
[/cpp]

Somewhere else in your startup code, you install your Unix signal handlers with sigaction(2)

[cpp]
static int setup_unix_signal_handlers()
{
struct sigaction hup, term;

hup.sa_handler = MyDaemon::hupSignalHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags = 0;
hup.sa_flags |= SA_RESTART;

if (sigaction(SIGHUP, &hup, 0) > 0)
return 1;

term.sa_handler = MyDaemon::termSignalHandler;
sigemptyset(&term.sa_mask);
term.sa_flags |= SA_RESTART;

if (sigaction(SIGTERM, &term, 0) > 0)
return 2;

return 0;
}
[/cpp]

In your Unix signal handlers, you write a byte to the write end of a socket pair and return. This will cause the corresponding QSocketNotifier to emit its activated() signal, which will in turn cause the appropriate Qt slot function to run.

[cpp]
void MyDaemon::hupSignalHandler(int)
{
char a = 1;
::write(sighupFd[0], &a, sizeof(a));
}

void MyDaemon::termSignalHandler(int)
{
char a = 1;
::write(sigtermFd[0], &a, sizeof(a));
}
[/cpp]

In the slot functions connected to the QSocketNotifier::activated() signals, you read the byte. Now you are safely back in Qt with your signal, and you can do all the Qt stuff you weren’tr allowed to do in the Unix signal handler.

[cpp]
void MyDaemon::handleSigTerm()
{
snTerm->setEnabled(false);
char tmp;
::read(sigtermFd[1], &tmp, sizeof(tmp));

// do Qt stuff

snTerm->setEnabled(true);
}

void MyDaemon::handleSigHup()
{
snHup->setEnabled(false);
char tmp;
::read(sighupFd[1], &tmp, sizeof(tmp));

// do Qt stuff

snHup->setEnabled(true);
}
[/cpp]

Linux系统调用列表

Posted by – April 16, 2010

Linux系统调用列表:

Refers to:
http://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html#2

2002 年 3 月 01 日

本文列出了大部分常见的Linux系统调用,并附有简要中文说明。

以下是Linux系统调用的一个列表,包含了大部分常用系统调用和由系统调用派生出的的函数。这可能是你在互联网上所能看到的唯一一篇中文注释的 Linux系统调用列表,即使是简单的字母序英文列表,能做到这么完全也是很罕见的。

按照惯例,这个列表以man pages第2节,即系统调用节为蓝本。按照笔者的理解,对其作了大致的分类,同时也作了一些小小的修改,删去了几个仅供内核使用,不允许用户调用的系统 调用,对个别本人稍觉不妥的地方作了一些小的修改,并对所有列出的系统调用附上简要注释。

其中有一些函数的作用完全相同,只是参数不同。(可能很多熟悉C++朋友马上就能联想起函数重载,但是别忘了Linux核心是用C语言写的,所以只能取成 不同的函数名)。还有一些函数已经过时,被新的更好的函数所代替了(gcc在链接这些函数时会发出警告),但因为兼容的原因还保留着,这些函数我会在前面 标上“*”号以示区别。

一、进程控制:

fork 创建一个新进程
clone 按指定条件创建子 进程
execve 运行可执行文件
exit 中 止进程
_exit 立即中止当前进程
getdtablesize 进 程所能打开的最大文件数
getpgid 获取指定进程组标识号
setpgid 设 置指定进程组标志号
getpgrp 获取当前进程组标识号
setpgrp 设 置当前进程组标志号
getpid 获取进程标识号
getppid 获 取父进程标识号
getpriority 获取调度优先级
setpriority 设 置调度优先级
modify_ldt 读写进程的本地描述表
nanosleep 使 进程睡眠指定的时间
nice 改变分时进程的优先级
pause 挂 起进程,等待信号
personality 设置进程运行域
prctl 对 进程进行特定操作
ptrace 进程跟踪
sched_get_priority_max 取 得静态优先级的上限
sched_get_priority_min 取得静态优先级的下限
sched_getparam 取 得进程的调度参数
sched_getscheduler 取得指定进程的调度策略
sched_rr_get_interval 取 得按RR算法调度的实时进程的时间片长度
sched_setparam 设置进程的调度参数
sched_setscheduler 设 置指定进程的调度策略和参数
sched_yield 进程主动让出处理器,并将自己等候调度队列队 尾
vfork 创建一个子进程,以供执行新程序,常与execve等同时使用
wait 等 待子进程终止
wait3 参见wait
waitpid 等 待指定子进程终止
wait4 参见waitpid
capget 获 取进程权限
capset 设置进程权限
getsid 获 取会晤标识号
setsid 设置会晤标识号

回页首

二、文件系统控制

1、文件读写操作

fcntl 文件控制
open 打开文件
creat 创 建新文件
close 关闭文件描述字
read 读 文件
write 写文件
readv 从文件 读入数据到缓冲数组中
writev 将缓冲数组里的数据写入文件
pread 对 文件随机读
pwrite 对文件随机写
lseek 移 动文件指针
_llseek 在64位地址空间里移动文件指针
dup 复 制已打开的文件描述字
dup2 按指定条件复制文件描述字
flock 文 件加/解锁
poll I/O多路转换
truncate 截 断文件
ftruncate 参见truncate
umask 设 置文件权限掩码
fsync 把文件在内存中的部分写回磁盘

2、文件系统操作

access 确定文件的可存取性
chdir 改变当前 工作目录
fchdir 参见chdir
chmod 改 变文件方式
fchmod 参见chmod
chown 改 变文件的属主或用户组
fchown 参见chown
lchown 参 见chown
chroot 改变根目录
stat 取 文件状态信息
lstat 参见stat
fstat 参 见stat
statfs 取文件系统信息
fstatfs 参 见statfs
readdir 读取目录项
getdents 读 取目录项
mkdir 创建目录
mknod 创 建索引节点
rmdir 删除目录
rename 文 件改名
link 创建链接
symlink 创 建符号链接
unlink 删除链接
readlink 读 符号链接的值
mount 安装文件系统
umount 卸 下文件系统
ustat 取文件系统信息
utime 改 变文件的访问修改时间
utimes 参见utime
quotactl 控 制磁盘配额

回页首

三、系统控制

ioctl I/O总控制函数
_sysctl 读/写系 统参数
acct 启用或禁止进程记账
getrlimit 获 取系统资源上限
setrlimit 设置系统资源上限
getrusage 获 取系统资源使用情况
uselib 选择要使用的二进制函数库
ioperm 设 置端口I/O权限
iopl 改变进程I/O权限级别
outb 低 级端口操作
reboot 重新启动
swapon 打 开交换文件和设备
swapoff 关闭交换文件和设备
bdflush 控 制bdflush守护进程
sysfs 取核心支持的文件系统类型
sysinfo 取 得系统信息
adjtimex 调整系统时钟
alarm 设 置进程的闹钟
getitimer 获取计时器值
setitimer 设 置计时器值
gettimeofday 取时间和时区
settimeofday 设 置时间和时区
stime 设置系统日期和时间
time 取 得系统时间
times 取进程运行时间
uname 获 取当前UNIX系统的名称、版本和主机等信息
vhangup 挂起当前终端
nfsservctl 对 NFS守护进程进行控制
vm86 进入模拟8086模式
create_module 创 建可装载的模块项
delete_module 删除可装载的模块项
init_module 初 始化模块
query_module 查询模块信息
*get_kernel_syms 取 得核心符号,已被query_module代替

回页首

四、内存管理

brk 改变数据段空间的分配
sbrk 参见brk
mlock 内 存页面加锁
munlock 内存页面解锁
mlockall 调 用进程所有内存页面加锁
munlockall 调用进程所有内存页面解锁
mmap 映 射虚拟内存页
munmap 去除内存页映射
mremap 重 新映射虚拟内存地址
msync 将映射内存中的数据写回磁盘
mprotect 设 置内存映像保护
getpagesize 获取页面大小
sync 将 内存缓冲区数据写回硬盘
cacheflush 将指定缓冲区中的内容写回磁盘

回页首

五、网络管理

getdomainname 取域名
setdomainname 设 置域名
gethostid 获取主机标识号
sethostid 设 置主机标识号
gethostname 获取本主机名称
sethostname 设 置主机名称

回页首

六、socket控制

socketcall socket系统调用
socket 建 立socket
bind 绑定socket到端口
connect 连 接远程主机
accept 响应socket连接请求
send 通 过socket发送信息
sendto 发送UDP信息
sendmsg 参 见send
recv 通过socket接收信息
recvfrom 接 收UDP信息
recvmsg 参见recv
listen 监 听socket端口
select 对多路同步I/O进行轮询
shutdown 关 闭socket上的连接
getsockname 取得本地socket名字
getpeername 获 取通信对方的socket名字
getsockopt 取端口设置
setsockopt 设 置端口参数
sendfile 在文件或端口间传输数据
socketpair 创 建一对已联接的无名socket

回页首

七、用户管理

getuid 获取用户标识号
setuid 设置用户标 志号
getgid 获取组标识号
setgid 设 置组标志号
getegid 获取有效组标识号
setegid 设 置有效组标识号
geteuid 获取有效用户标识号
seteuid 设 置有效用户标识号
setregid 分别设置真实和有效的的组标识号
setreuid 分 别设置真实和有效的用户标识号
getresgid 分别获取真实的,有效的和保存过的组标识号
setresgid 分 别设置真实的,有效的和保存过的组标识号
getresuid 分别获取真实的,有效的和保存过的用 户标识号
setresuid 分别设置真实的,有效的和保存过的用户标识号
setfsgid 设 置文件系统检查时使用的组标识号
setfsuid 设置文件系统检查时使用的用户标识号
getgroups 获 取后补组标志清单
setgroups 设置后补组标志清单

回页首

八、进程间通信

ipc 进程间通信总控制调用

1、信号

sigaction 设置对指定信号的处理方法
sigprocmask 根 据参数对信号集中的信号执行阻塞/解除阻塞等操作
sigpending 为指定的被阻塞信号设置队 列
sigsuspend 挂起进程等待特定信号
signal 参 见signal
kill 向进程或进程组发信号
*sigblock 向 被阻塞信号掩码中添加信号,已被sigprocmask代替
*siggetmask 取得现有阻塞 信号掩码,已被sigprocmask代替
*sigsetmask 用给定信号掩码替换现有阻塞信 号掩码,已被sigprocmask代替
*sigmask 将给定的信号转化为掩码,已被 sigprocmask代替
*sigpause 作用同sigsuspend,已被 sigsuspend代替
sigvec 为兼容BSD而设的信号处理函数,作用类似 sigaction
ssetmask ANSI C的信号处理函数,作用类似sigaction

2、消息

msgctl 消息控制操作
msgget 获取消息队列
msgsnd 发 消息
msgrcv 取消息

3、管道

pipe 创建管道

4、信号量

semctl 信号量控制
semget 获取一组信号量
semop 信 号量操作

5、共享内存

shmctl 控制共享内存
shmget 获取共享内存
shmat 连 接共享内存
shmdt 拆卸共享内存

参考资料

  • Linux man pages
  • Advanced Programming in the UNIX Environment, W. Richard Stevens, 1993

SDL/FFmpeg

Posted by – March 17, 2010

ffmpeg:

http://ffmpeg.org/  (official website)
http://dranger.com/ffmpeg/
http://www.inb.uni-luebeck.de/~boehme/using_libavcodec.html
http://cekirdek.pardus.org.tr/~ismail/ffmpeg-docs/functions.html
http://www.ffmpeg.com.cn/

FFmpeg Documentation:
http://cekirdek.pardus.org.tr/~ismail/ffmpeg-docs/

SDL:

http://www.libsdl.org/ ( official website)

SDL开发环境的建立:

http://blog.chinaunix.net/u/19671/article_31020.html

SDK quick start:
http://blog.csdn.net/wstarx/archive/2007/04/20/1572393.aspx

FFMpeg框架代码阅读:

Refer to:
http://blog.csdn.net/wstarx/archive/2007/04/20/1572393.aspx
内容摘要:

FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。FFmpeg的 开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用。FFmpeg支持MPEG、 DivX、MPEG4、AC3、DV、FLV等40多种编码,AVI、MPEG、OGG、Matroska、ASF等90多种解码. TCPMP, VLC, MPlayer等开源播放器都用到了FFmpeg。 FFmpeg主目录下主要有libavcodec、libavformat和libavutil等子目录

1. 简介
FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。FFmpeg的
开发是基于Linux操作系统,但是可以在大多数操作系统中编译和使用。FFmpeg支持MPEG、
DivX、MPEG4、AC3、DV、FLV等40多种编码,AVI、MPEG、OGG、Matroska、ASF等90多种解码.
TCPMP, VLC, MPlayer等开源播放器都用到了FFmpeg。
FFmpeg主目录下主要有libavcodec、libavformat和libavutil等子目录。其中libavcodec用
于存放各个encode/decode模块,libavformat用于存放muxer/demuxer模块,libavutil用于
存放内存操作等辅助性模块。
以flash movie的flv文件格式为例, muxer/demuxer的flvenc.c和flvdec.c文件在
libavformat目录下,encode/decode的mpegvideo.c和h263de.c在libavcodec目录下。

2. muxer/demuxer与encoder/decoder定义与初始化
muxer/demuxer和encoder/decoder在FFmpeg中的实现代码里,有许多相同的地方,而二者最
大的差别是muxer 和demuxer分别是不同的结构AVOutputFormat与AVInputFormat,而encoder
和decoder都是用的AVCodec 结构。

muxer/demuxer和encoder/decoder在FFmpeg中相同的地方有:
二者都是在main()开始的av_register_all()函数内初始化的
二者都是以链表的形式保存在全局变量中的
muxer/demuxer是分别保存在全局变量AVOutputFormat *first_oformat与
AVInputFormat *first_iformat中的。
encoder/decoder都是保存在全局变量AVCodec *first_avcodec中的。
二者都用函数指针的方式作为开放的公共接口

demuxer开放的接口有:
int (*read_probe)(AVProbeData *);
int (*read_header)(struct AVFormatContext *, AVFormatParameters *ap);
int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
int (*read_close)(struct AVFormatContext *);
int (*read_seek)(struct AVFormatContext *, int stream_index, int64_t timestamp, int flags);

muxer开放的接口有:
int (*write_header)(struct AVFormatContext *);
int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
int (*write_trailer)(struct AVFormatContext *);

encoder/decoder的接口是一样的,只不过二者分别只实现encoder和decoder函数:
int (*init)(AVCodecContext *);
int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
int (*close)(AVCodecContext *);
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, uint8_t *buf, int buf_size);

仍以flv文件为例来说明muxer/demuxer的初始化。
在libavformat\allformats.c文件的av_register_all(void)函数中,通过执行
REGISTER_MUXDEMUX(FLV, flv);
将支持flv 格式的flv_muxer与flv_demuxer变量分别注册到全局变量first_oformat与first_iformat链表的最后位置。
其中flv_muxer在libavformat\flvenc.c中定义如下:
AVOutputFormat flv_muxer = {
“flv”,
“flv format”,
“video/x-flv”,
“flv”,
sizeof(FLVContext),
#ifdef CONFIG_LIBMP3LAME
CODEC_ID_MP3,
#else // CONFIG_LIBMP3LAME
CODEC_ID_NONE,
CODEC_ID_FLV1,
flv_write_header,
flv_write_packet,
flv_write_trailer,
.codec_tag= (const AVCodecTag*[]){flv_video_codec_ids, flv_audio_codec_ids, 0},
}

AVOutputFormat结构的定义如下:
typedef struct AVOutputFormat {
const char *name;
const char *long_name;
const char *mime_type;
const char *extensions; /**< comma separated filename extensions */
/** size of private data so that it can be allocated in the wrapper */
int priv_data_size;
/* output support */
enum CodecID audio_codec; /**< default audio codec */
enum CodecID video_codec; /**< default video codec */
int (*write_header)(struct AVFormatContext *);
int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
int (*write_trailer)(struct AVFormatContext *);
/** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */
int flags;
/** currently only used to set pixel format if not YUV420P */
int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *);
int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, AVPacket *in, int flush);

/**
*list of supported codec_id-codec_tag pairs,ordered by “better choice first”
* the arrays are all CODEC_ID_NONE terminated
*/
const struct AVCodecTag **codec_tag;
/* private fields */
struct AVOutputFormat *next;
} AVOutputFormat;
由AVOutputFormat结构的定义可知,flv_muxer变量初始化的第一、二个成员分别为该muxer
的名称与长名称,第三、第四个成员为所对应MIMIE Type和后缀名,第五个成员是所对应的
私有结构的大小,第六、第七个成员为所对应的音频编码和视频编码类型ID,接下来就是三
个重要的接口函数,该 muxer的功能也就是通过调用这三个接口实现的。

flv_demuxer在libavformat\flvdec.c中定义如下, 与flv_muxer类似,在这儿主要也是设置
了5个接口函数,其中flv_probe接口用途是测试传入的数据段是否是符合当前文件格式,这
个接口在匹配当前demuxer时会用到。
AVInputFormat flv_demuxer = {
“flv”,
“flv format”,
0,
flv_probe,
flv_read_header,
flv_read_packet,
flv_read_close,
flv_read_seek,
.extensions = “flv”,
.value = CODEC_ID_FLV1,
};

在上述av_register_all(void)函数中通过执行libavcodec\allcodecs.c文件里的
avcodec_register_all(void)函数来初始化全部的encoder/decoder。

因为不是每种编码方式都支持encode和decode,所以有以下三种注册方式:
#define REGISTER_ENCODER(X,x) \
if(ENABLE_##X##_ENCODER) register_avcodec(&x##_encoder)
#define REGISTER_DECODER(X,x) \
if(ENABLE_##X##_DECODER) register_avcodec(&x##_decoder)
#define REGISTER_ENCDEC(X,x) REGISTER_ENCODER(X,x); REGISTER_DECODER(X,x)

如支持flv的flv_encoder和flv_decoder变量就分别是在libavcodec\mpegvideo.c和
libavcodec\h263de.c中创建的。

3. 当前muxer/demuxer的匹配
在FFmpeg的文件转换过程中,首先要做的就是根据传入文件和传出文件的后缀名[FIXME]匹配
合适的demuxer和muxer。匹配上的demuxer和muxer都保存在如下所示,定义在ffmpeg.c里的
全局变量file_iformat和file_oformat中:
static AVInputFormat *file_iformat;
static AVOutputFormat *file_oformat;

3.1 demuxer匹配
在libavformat\utils.c中的static AVInputFormat *av_probe_input_format2(
AVProbeData *pd, int is_opened, int *score_max)函数用途是根据传入的probe data数据
,依次调用每个demuxer的read_probe接口,来进行该demuxer是否和传入的文件内容匹配的
判断。其调用顺序如下:
void parse_options(int argc, char **argv, const OptionDef *options,
void (* parse_arg_function)(const char *));
static void opt_input_file(const char *filename)
int av_open_input_file(…… )
AVInputFormat *av_probe_input_format(AVProbeData *pd,
int is_opened)
static AVInputFormat *av_probe_input_format2(……)
opt_input_file函数是在保存在const OptionDef options[]数组中,用于
void parse_options(int argc, char **argv, const OptionDef *options)中解析argv里的
“-i” 参数,也就是输入文件名时调用的。

3.2 muxer匹配
与demuxer的匹配不同,muxer的匹配是调用guess_format函数,根据main() 函数的argv里的
输出文件后缀名来进行的。
void parse_options(int argc, char **argv, const OptionDef *options,
void (* parse_arg_function)(const char *));
void parse_arg_file(const char *filename)
static void opt_output_file(const char *filename)
AVOutputFormat *guess_format(const char *short_name,
const char *filename,
const char *mime_type)

3.3 当前encoder/decoder的匹配
在main()函数中除了解析传入参数并初始化demuxer与muxer的parse_options( )函数以外,
其他的功能都是在av_encode( )函数里完成的。
在libavcodec\utils.c中有如下二个函数:
AVCodec *avcodec_find_encoder(enum CodecID id)
AVCodec *avcodec_find_decoder(enum CodecID id)
他们的功能就是根据传入的CodecID,找到匹配的encoder和decoder。

在av_encode( )函数的开头,首先初始化各个AVInputStream和AVOutputStream,然后分别调
用上述二个函数,并将匹配上的encoder与decoder分别保存在:
AVInputStream->AVStream *st->AVCodecContext *codec->struct AVCodec *codec与
AVOutputStream->AVStream *st->AVCodecContext *codec->struct AVCodec *codec变量。

4. 其他主要数据结构
4.1 AVFormatContext
AVFormatContext是FFMpeg格式转换过程中实现输入和输出功能、保存相关数据的主要结构。
每一个输入和输出文件,都在如下定义的指针数组全局变量中有对应的实体。
static AVFormatContext *output_files[MAX_FILES];
static AVFormatContext *input_files[MAX_FILES];
对于输入和输出,因为共用的是同一个结构体,所以需要分别对该结构中如下定义的iformat
或oformat成员赋值。
struct AVInputFormat *iformat;
struct AVOutputFormat *oformat;
对一个AVFormatContext来说,这二个成员不能同时有值,即一个AVFormatContext不能同时
含有demuxer和muxer。在main( )函数开头的parse_options( )函数中找到了匹配的muxer和
demuxer之后,根据传入的argv参数,初始化每个输入和输出的AVFormatContext结构,并保
存在相应的output_files和input_files指针数组中。在av_encode( )函数中,output_files
和input_files是作为函数参数传入后,在其他地方就没有用到了。

4.2 AVCodecContext
保存AVCodec指针和与codec相关数据,如video的width、height,audio的sample rate等。
AVCodecContext中的codec_type,codec_id二个变量对于encoder/decoder的匹配来说,最为
重要。
enum CodecType codec_type;     /* see CODEC_TYPE_xxx */
enum CodecID codec_id;         /* see CODEC_ID_xxx */

如上所示,codec_type保存的是CODEC_TYPE_VIDEO,CODEC_TYPE_AUDIO等媒体类型,
codec_id保存的是CODEC_ID_FLV1,CODEC_ID_VP6F等编码方式。

以支持flv格式为例,在前述的av_open_input_file(…… ) 函数中,匹配到正确的
AVInputFormat demuxer后,通过av_open_input_stream( )函数中调用AVInputFormat的
read_header接口来执行flvdec.c中的flv_read_header( )函数。在flv_read_header( )函数
内,根据文件头中的数据,创建相应的视频或音频AVStream,并设置AVStream中
AVCodecContext的正确的codec_type值。codec_id值是在解码过程中flv_read_packet( )函
数执行时根据每一个packet头中的数据来设置的。

4.3 AVStream
AVStream结构保存与数据流相关的编解码器,数据段等信息。比较重要的有如下二个成员:
AVCodecContext *codec; /**< codec context */
void *priv_data;
其中codec指针保存的就是上节所述的encoder或decoder结构。priv_data指针保存的是和具
体编解码流相关的数据,如下代码所示,在ASF的解码过程中,priv_data保存的就是
ASFStream结构的数据。
AVStream *st;
ASFStream *asf_st;
… …
st->priv_data = asf_st;

4.4 AVInputStream/ AVOutputStream
根据输入和输出流的不同,前述的AVStream结构都是封装在AVInputStream和AVOutputStream
结构中,在av_encode( )函数中使用。AVInputStream中还保存的有与时间有关的信息。
AVOutputStream中还保存有与音视频同步等相关的信息。

4.5 AVPacket
AVPacket结构定义如下,其是用于保存读取的packet数据。
typedef struct AVPacket {
int64_t pts;            ///< presentation time stamp in time_base units
int64_t dts;            ///< decompression time stamp in time_base units
uint8_t *data;
int   size;
int   stream_index;
int   flags;
int   duration;        ///< presentation duration in time_base units (0 if not available)
void (*destruct)(struct AVPacket *);
void *priv;
int64_t pos;           ///< byte position in stream, -1 if unknown
} AVPacket;

在av_encode()函数中,调用AVInputFormat的
(*read_packet)(struct AVFormatContext *, AVPacket *pkt)接口,读取输入文件的一帧数
据保存在当前输入AVFormatContext的AVPacket成员中。

5. av_encode函数主要流程
av_encode()函数是FFMpeg中最重要的函数,编解码和输出等大部分功能都在此函数完成,
因此有必要详细描述一下这个函数的主要流程。
1).input streams initializing
2).output streams initializing
3).encoders and decoders initializing
4).set meta data information from input file if required.
5).write output files header
6).loop of handling each frame
a.read frame from input file:
b.decode frame data
c.encode new frame data
d.write new frame to output file
7).write output files trailer
8).close each encoder and decoder

解决QT静态编译和debug库问题

Posted by – March 13, 2010

解决QT静态编译和debug库问题(mingwm10.dll丢失、collect2:ld returned 1 exit status)
通过网上到处找资料,终于搞定了遇到的问题,相信其它人也会遇到,我就把解决方法非写出来了:

平台:windows7   软件:qt4.6+qt creator 1.3     使用的安装包是  qt-sdk-win-opensource-2009.05.exe

问题描述:
(1)使用 qt creator 生成工程,写好程序进行编译运行,在qt creator点击运行,程序能跑起来,没问题,可是我在工程目录下找到编译生成的程序双击运行时,提示缺少mingwm10.dll,无法运行。
(2) 按照 http://wiki.qtcentre.org/index.php?title=Building_static_Qt_on_Windows#MinGW 这个方法完成操作以后,使用qt creator 不能用debug,只能使用release选项,使用debug选项产生的错误提示是:collect2:ld returned 1 exit status    通过查找资料发现是缺少debug库

——————————————————
解决方案:
(1)编辑 C:\Qt\2009.05\qt\mkspecs\win32-g++\qmake.conf 文件 把
QMAKE_LFLAGS =         -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
改为: QMAKE_LFLAGS = -static -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
(2)在开始菜单里找到Qt Command Prompt并运行,输入命令:   configure -static -debug-and-release -no-exceptions
(3)上一条命令运行成功后再输入命令:   mingw32-make sub-src
等1 ~3 小时可能就运行完了   完成后就ok了。。。
已经在我的机子上验证,祝大家好运!

Q: 首先得谢谢楼主让我解决了不能debug的问题。。。但是又产生了新的问题,现在debug生成的可执行文件太大了。。。一百多兆啊,release生成的才八九M。。。这是怎么回事儿呢?

A: Debug时当然用debug了,大一点没关系。Debug 完之后正式发布软件再用release编译一遍。然后还可以strip(Linux 程序) 一下exe、在upx(http://upx.sourceforge.net/#download)一下exe和dll,体积会非常小。

QT手册& 汉化Chinesize

Posted by – January 5, 2010

QT手册& 汉化Chinesize:
http://blog.chinaunix.net/u/26313/showart_213711.html

嵌入式工具Qt的安装与使用
——————————————————————————–

摘要
Qt是Trolltech公司的一个产品。Trolltech是挪威的一家软件公司,主要开发两种产品:一种是跨平台应用程序界面框架;另外一种就是提供给做嵌入式Linux开发的应用程序平台,能够应用到PDA和各种移动设备上。Qt和 Qtopia分别是其中具有代表性的两个。

By lanf, 出处:http://tech.ccidnet.com/pub/article/c310_a71173_p1.html

作者:胡利民 本文选自:开放系统世界

Qt是Trolltech公司的一个产品。Trolltech是挪威的一家软件公司,主要开发两种产品:一种是跨平台应用程序界面框架;另外一种就是提供给做嵌入式Linux开发的应用程序平台,能够应用到PDA和各种移动设备上。Qt和Qtopia分别是其中具有代表性的两个。

Qt是一个多平台的C++图形用户界面应用程序框架,它能给用户提供精美的图形用户界面所需要的所有元素,而且它是基于一种面向对象的思想,所以用户对其对象的扩展是相当容易的,并且它还支持真正的组件编程。

Qt是Linux桌面环境KDE的基础。笔者认为,可以说Qt与Windows下的Mfc的实质是一样的,所以Qt最大的优点在于其跨平台性,可以支持现有的多种操作系统平台,主要有:

◆ MS/Windows 95、Windows 98、WindowsNT 4.0、Windows 2000、Windows XP;

◆ Unix/X11 Linux、Sun Solaris、HP-UX、Compaq True64Unix、IBM AIX、SGI IRIX和很多其它X11平台;

◆ Macintoshi Mac OSX;

◆ Embedded—带FramBuffer的Linux平台。

下面简单介绍一下Qt/Embedded和Qtopia在Linux上的安装和使用,还有在开发过程中可能碰到的一些问题。

Qt 和Qtopia的安装

如果需要安装一个带FramBuffer的Qtopia平台,需要有以下软件(所列举软件以笔者使用的为例):

◆ Qtopia 1.6.0;

◆ Tmake 1.11;

◆ Qt/Embedded 2.3.4(Qtopia 1.6.0是基于该开发平台上开发的);

◆ Qt/Embedded 2.3.2 for X11;

◆ Qt 3.1.2 for X11。

在Trolltech公司的网站上可以下载该公司所提供的Qt/Embedded的免费版本。

Qtopia平台安装分为以下几个步骤:

1. 解包Qtopia

在Linux命令模式下运行以下命令:

tar xfz qtopia-source-1.6.0 (解包)
cd qtopia-source-1.6.0
export QPEDIR=$PWD (设置环境变量)
cd..

2. 安装Tmake

在Linux命令模式下运行以下命令:

tar xfz tmake-1.11.tar.gz
export TMAKEDIR=$PWD/tmake-1.11
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
export PATH=$TMAKEDIR/bin:$PATH

3. 安装Qt/Embedded2.3.4

在Linux命令模式下运行以下命令:

tar xfz qt-embedded-2.3.4-commercial.tar.gz
cd qt-2.3.4
export QTDIR=$PWD
export QTEDIR=$QTDIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
cp $QPEDIR/src/qt/qconfig-qpe.h src/tools/
. /configure -qconfig qpe -qvfb -depths 4,8,16,32
make sub-src
cd ..

也可以在configure的参数中添加-system-jpeg和gif,使Qtopia平台能支持jpeg、gif格式的图形。

4. 安装Qt/X11 2.3.2

在Linux命令模式下运行以下命令:

tar xfz qt-x11-2.3.2-commercial.tar.gz
cd qt-2.3.2
export QTDIR=$PWD
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
cp bin/uic $QTEDIR/bin
cd ..

根据开发者本身的开发环境,也可以在configure的参数中添加别的参数,比如-no-opengl或-no-xfs,可以键入./configure -help来获得一些帮助信息。

5. 安装Qt/X11 3.1.2

在Linux命令模式下运行以下命令:

tar xfz qt-x11-commercial-3.1.x.tar.gz
cd qt-x11-commercial-3.1.x
export QTDIR=$PWD
export QT3DIR=$QTDIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure -thread
make
cd ..

6. 安装Qtopia

在Linux命令模式下运行以下命令:

cd qtopia-source-1.6.x
export QTDIR=$QTEDIR
export QPEDIR=$PWD
export PATH=$QPEDIR/bin:$PATH
cd src
./configure
make
cd ../..

7. 安装Qtopia桌面

cd qtopia-source-1.6.x/src
export QTDIR=$QT3DIR
./configure -qtopiadesktop
make
mv qtopiadesktop/bin/qtopiadesktop ../bin
cd ..

Qt和Qt Designer的使用
——————————————————————————–
根据上面的步骤安装完成了Qt/Embedded和Qtopia之后,就可以运行这些程序了。

运行Qt的虚拟仿真窗口:在Linux的图形模式下运行命令qvfb&;Qtopia只是一个用Qt/Embedded开发的程序,运行Qtopia,在图形模式下运行命令:

export QTDIR=$QTEDIR,
qpe &;

这样Qtopia的程序就运行在QVFB上,即Qt的虚拟仿真窗口。

Qt/Embedded是针对嵌入式Linux而开发的一种开发工具,Qt封装了一些常用的类,而且这些类的名字都以Q字开头命名,如QString、QDialog等。这里主要介绍一下如何利用Qt Designer来设计组件,并生成相应的代码。

在Qt中,把组件分为复合体、原始体和配件。而在Qt中,组件是由一些抽象类、复杂的组件类、管理组件几何特性的类等组成。

Qt中有三个主要的基类:QObject、Qapplication和QWidget。

在Qt 中编程,利用Signal和Slot进行对象之间的通信是Qt的主要特征。它与Windows中的消息机制非常类似,但是Signal和Slot机制真正实现了一种消息的封装。当对象的状态改变时,发出Signal,通知所有的Slot接受Signal,尽管它不知道哪些函数是Slot,Slot一开始也不知道哪些Signal可以接收。Signal和Slot之间不是一一对应的关系,一个Signal可以发给多个Slot, Slot也可以接收多个Signal。Slot除了可以接收Signal以外,与其它的成员函数没有区别。这种机制比使用回调函数要灵活,但是会减慢程序的运行速度。不过在现在高速CPU的面前,这种损失是无足轻重的,而且它还能保证程序的简明性和灵活性,非常便利。

在Qt的组件中,不仅定义了常用的成员变量和成员函数,还定义了所有与该组件相关的Signal和Slot。

要将组件组合起来,最简单的方法就是使用Qt Designer。首先要启动Qt Designer,在Linux命令模式下,键入以下命令(假设Qt安装在/usr/local下):

cd qt-2.3.2/bin
./designer

这样就可以启动一个与Windows下的Delphi相类似的界面。

然后新建一个QFrame,将自己需要的组件直接拖拉到这个Frame中,相信很多人都有过这样的经历,此处就不再详细描述了。完成之后存盘时,会将这个新的组件保存为一个扩展名为.ui的文件。假设所存的文件名为test.ui,用vi test.ui来查看这个文件,发现这是一个用xml语言写的一个文本。下面用这个test.ui生成相应的test.h和test.cpp。同样还是在这个目录下,可以看到一个uic的工具,这个是Qt专门用来将ui文件生成.h和.cpp文件的,在终端模式下键入以下命令:

./uic -o test.h test.ui
./uic -o test.h -i test.cpp test.ui

此时就能看到生成了相应test.h和test.cpp,这是一个类。当然这只是一些表面的东西,还需要在这些代码中添加相应的Signal和Slot,完成所需要的操作。值得注意的是,相应版本生成的ui最好用相应版本的uic来生成代码。如果用Qt 3.1.2的Designer生成的ui,用Qt 2.3.2的uic来生成代码,生成的代码都会是一些空函数。

在一般的开发过程中,首先通过这个ui生成的一个类,在Qt中通常叫做 Base,如上面的例子,叫做testBase;然后再新建一个类,来继承这个Base。通常叫做实现类Impl,如testImpl。在这个实现类里面定义所需要的成员函数、Signal和Slot,因为ui可能是经常需要改动的。如果这样做,每次只需要在Designer中修改ui,而不用去理会这些成员函数、Signal和Slot了。

编译一个Qt程序必然需要Makefile,在Qt中提供了一个专门生成Makefile的工具,就是tmake。用tmake需要根据编写的程序写一个.pro文件。.pro文件非常简单,有固定的格式,下面是一个例子:

TEMPLATE = app
CONFIG = qtopia warn_on release
MOC_DIR =tmp
OBJECTS_DIR =tmp
HEADERS =fcrs.h\
structs.h \
globalfunc.h \
globalvars.h \
testimpl.h
SOURCES = main.cpp \
globalfunc.cpp\
globalvars.cpp \
testimpl.cpp
INTERFACES = test.ui \
TARGET = fcrs

生成这个.pro文件之后,在终端中键入下面的命令:

tmake -o Makefile test.pro

就自动生成了一个Makefile,使用这个Makefile编译所编写的程序就可以了。

Qt/Embedded开发环境建立的过程
——————————————————————————–

Qt/Embedded开发环境建立的过程:
(这些软件可以免费从trolltech的WEB或FTP服务器上下载)
◆ tmake 1.11 或更高版本; (生成Qt/Embedded应用工程的Makefile文件)
◆ Qt/Embedded 2.3.7 (Qt/Embedded 安装包)
◆ Qt 2.3.2 for X11; (Qt的X11版的安装包, 它将产生x11开发环境所需要的两个工具)
1、安装tmake
在Linux 命令模式下运行以下命令:
tar xfz tmake-1.11.tar.gz
export TMAKEDIR=$PWD/tmake-1.11
export TMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
export PATH=$TMAKEDIR/bin:$PATH
2. 安装Qt/Embedded 2.3.7
在Linux 命令模式下运行以下命令:
tar xfz qt-embedded-2.3.7.tar.gz
cd qt-2.3.7
export QTDIR=$PWD
export QTEDIR=$QTDIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure -qconfig -qvfb -depths 4,8,16,32
make sub-src
cd ..
上述命令 ./configure -qconfig -qvfb -depths 4,8,16,32 指定Qt 嵌入式开发包生
成虚拟缓冲帧工具qvfb,并支持4,8,16,32 位的显示颜色深度。另外我们也可以在
configure 的参数中添加-system-jpeg 和gif,使Qt/Embedded 平台能支持jpeg、gif
格式的图形。
上述命令 make sub-src 指定按精简方式编译开发包,也就是说有些Qt 类未被编
译。Qt 嵌入式开发包有5 种编译范围的选项,使用这些选项,可控制Qt 生成的库文件的大
小,但是您的应用所使用到的一些Qt 类将可能因此在Qt 的库中找不到链接。编译选项的具
体用法可运行./configure -help 命令查看。
3. 安装Qt/X11 2.3.2
在Linux 命令模式下运行以下命令:
tar xfz qt-x11-2.3.2.tar.gz
cd qt-2.3.2
export QTDIR=$PWD
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
cp bin/uic $QTEDIR/bin
cd ..
根据开发者本身的开发环境,也可以在configure 的参数中添加别的参数,比如
-no-opengl 或-no-xfs,可以键入./configure -help 来获得一些帮助信息。
如果Qt/Embedded 的应用是在UNIX 平台下开发的话,那么它就可以在开发的机器
上以一个独立的控制台或者虚拟缓冲帧的方式来运行,对于后者来说,其实是有一个X11
的应用程序虚拟了一个缓冲帧。通过指定显示设备的宽度,高度和颜色深度,虚拟出来
的缓冲帧将和物理的显示设备在每个像素上保持一致。这样每次调试应用时开发人员就
不用总是刷新嵌入式设备的FLASH 存储空间,从而加速了应用的编译、链接和运行周期。
运行Qt 的虚拟缓冲帧工具的方法是:在Linux 的图形模式下运行命令:
qvfb (回车)
当Qt 嵌入式的应用程序要把显示结果输出到虚拟缓冲帧时,我们在命令行运行这
个程序时,在程序名后加上-qws 的选项。例如: $> hello -qws

一,QT/E的安装。
——————————————————————————–
在本机中安装了包括QT4.0.1(WINDOWS版本)以及QT/E2。3。7(LINUX版本)。
QT/E我安装在我的虚拟机中。因为QT/E2.3.7的版本问题,其适宜在REDHAT9。0版本(或更低版本)下安装,否则安装不成功。
QT/E安装过程复杂,具体细节可以参考下面这篇文章。《Qt/Embedded开发环境建立的过程》
此文在网上可搜索到。

本机下虚拟机中QT/E安装路径为:/home/wangxl/QTE/qt-2.3.7
QT/X11安装路径为:/home/wangxl/QTE/qt-2.3.2
Tmake安装路径为:/home/wangxl/QTE/Tmake-1.8

QT/E下载地址为:ftp://ftp.rediris.es/mirror/Qt/source/
Tmake下载地址为:ftp://ftp.trolltech.com/freebies/tmake/

二.QT与QT/E以及QT3与QT4之间的区别
——————————————————————————–
相对来说QT与QT/E的语法一样,所不同之处在库类大小或者库类函数大小不同而已。QT/E相对于QT来说,不具有少数类或者少数函数的支持。具体QT/E是否包含某个类或者包含某个类中的函数,我的方法是在QT/E安装目录下的include文件夹中去查找。
QT3和QT4有很多不同点,主要不同也是在于库类以及支持函数有所变化,比如,有些QT3中的函数,在QT4中被其他函数名所代替,因此很多QT4程序在QT3环境下无法执行。QT/E2.3.7与QT3基本相同,除了我前面提到的QT与QT/E的差别。

三.QT/E编译与执行。
——————————————————————————–
1.在QT/E编译与执行前要先设置TMAKE与QT/E LIB环境,具体方法如下:
[root@localhost tmake-1.8]# export TMAKEDIR=$PWD
[root@localhost tmake-1.8]# export TMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
[root@localhost tmake-1.8]# export PATH=$TMAKEDIR/bin:$PATH
[root@localhost qt-2.3.7]# export QTDIR=$PWD
[root@localhost qt-2.3.7]#export QTEDIR=$QTDIR
[root@localhost qt-2.3.7]#export PATH=$QTDIR/bin:$PATH
[root@localhost qt-2.3.7]#export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

2.如果你是用DESIGNER工具设计的界面(后面有讲),则要将*.ui文件转换成*.h文件和*.cpp文件。转换方法如下:
uic –o test.h test.ui
uic –o test.cpp –i test.h test.ui

3.编写一个*.pro文件(用来生成Makefile文件用),该文件格式比较固定。
如test.pro文件基本格式如下(以test.cpp ,test.h main.cpp为例子):
EMPLATE = app
CONFIG += qt warn_on release
HEADERS = test.h
SOURCES = test.cpp \
main.cpp
TARGET = hello
DEPENDPATH=/home/wangxl/QTE/qt-2.3.7/include
REQUIRES=

4.生成Makefile文件
方法为:tmake –o Makefile test.pro
5 编译生成可执行文件
make

6 打开QVFB
进入安装QT/X11所在目录, 在BIN目录下执行程序qvfb。
有时候需要修改qvfb执行时的deptb参数才能够执行QT/E程序。可以直接在QVFB打开窗口的Configure彩单项中选择,也可以用如下命令执行QVFB。
./qvfb –width ** -height ** -depth **
7.执行QT/E程序
如 。/TEST
在QVFB程序打开的窗口中将出现TEST程序的显示 。

四.Qt/e与QT/X11
——————————————————————————–
安装QT/E的同时还需要安装QT/X11与Tmake,Tmake 是用来帮助生成Makefile文件的。安装QT/X11主要是向QT/E提供designer工具和qvfb工具的。
Designer可以用来设计图形界面,最后生成.ui文件,可通过UIC命令转换为相应的C++文件。
QVFB模拟帧缓冲,提供QT/E程序的显示平台。

五.QT/E 程序ARM 板上执行
——————————————————————————–
在我虚拟机上可以执行的QT/E程序不能在ARM板上执行,需要对QT/E进行重新编译,并需要设置响对于ARM板系统的编译环境,具体方法可以参考我另外的一文《QT/E开发记录》

六.QT/E支持中文显示问题
——————————————————————————–
QT/E需要字体转换才能显示中文。具体方法可以参考我另外的一文《QT/E开发记录》
但是由于缺少UNICODE的QPF文件的字体,中文字大小不均匀问题尚没解决。

七 QT/E的一些参考资料:
——————————————————————————–
http://www.qtcn.org/bbs/index.php QT中文论坛
http://www.qiliang.net/qt/ (关于QT3的类,以及类函数可以在这寻找)
提供QT3编程最好书籍的电子版本《C++ GUI Programming with QT 3》(本机)
关于QT4可以参考QT ASSISTNAT(本机中),另外QT ASSISTNAT中也可以查找QT3的类及库等。

设置Qtopia的build环境
——————————————————————————–
1、环境变量
在目标系统上build Qtopia必须设定必要的环境变量,如QTDIR, 如果依赖多个版本的Qt,则需要用环境变量指向用到的库配置。
一种方法是将环境变量的设定写入文件,通过运行source命令应用文件的内容。

举例说明:
Linux/bash下建立环境变量设定文件qtopia.sh, 内容如下:
export QPEDIR=/opt/Qtopia
export QTDIR=/opt/Qtopia
export PATH=$QTDIR/bin:$PATH
export TMAKEPATH=/opt/Qtopia/tmake/lib/qws/linux-generic-g++
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

需要时运行 source qtopia.sh即可应用以上环境变量。

另外也可以通过在.bashrc文件中设定别名来应用这些环境变量。 假设环境变量设置文件存放在home目录的bin下, 则可在.bashrc中加入:
alias qtopia=’source ~/bin/qtopia.sh’

2、创建自定义的配置文件

整个Qtopia系统在build过程中需要三个独立的配置系统:
1) Qt/Embedded 配置文件
2) tmake – 用于build Qtopia 1.x和一些第三方软件
3) qmake – 用于build Qtopia 2及以上版本

在build Qtopia以前,先要完成以上三项的配置。

下面是创建一个“myarm”配置的例子:
cp -r $TMAKEDIR/lib/qws/linux-arm-g++ $TMAKEDIR/lib/qws/linux-myarm-g++
cp -r $QTEDIR/configs/linux-arm-g++-shared $QTEDIR/configs/linux-myarm-g++-shared
cp -r $QPEDIR/mkspecs/qws/linux-arm-g++ $QPEDIR/mkspecs/qws/linux-myarm-g++
Qt/Embedded
编辑$QTEDIR/configs/linux-myarm-g++-shared, 修改其中的utilities和flags成适合系统的内容, 如:
可能需要修改SYSCONF_CXX, SYSCONF_CC 和SYSCONF_LINK, 指定正确的编译器. 可能需要增加编译选项-DMYARM,在代码中增加宏#ifdef MYARM(用以增加设备相关的代码)
tmake
编辑$TMAKEDIR/lib/qws/linux-myarm-g++/tmake.conf,修改用到的utilites和flags:
可能需要修改TMAKE_CC, TMAKE_CXX 和TMAKE_LINK
可能需要增加-DMYARM选项
qmake

修改$QPEDIR/mkspecs/qws/linux-myarm-g++/qmake.conf:

QMAKE_CC, QMAKE_CXX 和QMAKE_LINK
-DMYARM
注意:qmake.conf的最后一行必须是:
exists($$(QPEDIR)/src/config.pri):include($$(QPEDIR)/src/config.pri)

可用于目录名的字符

正则表达式字符

Qtopia 1.9.x和Qtopia 2.0.0 – 2.1.0对字符有以下的要求:

Qtopia build系统访问到的任何目录都不能包含正则表达式字符
任何能被QRegExp识别的特殊字符和字符序列都可能引起问题
‘.’字符只匹配自身
不要将正则表达式字符用于目录名,包括(但不仅限于): + . ? * \ () [] ^ $ {}
注:Qtopia 2.1.0和2.1.1及以上版本可以通过应用patch解除以上的限制

空格

Qtopia build系统不支持目录名中包含空格。

必须保证:

build系统访问到的目录不包含空格
访问目录的各层上级目录也不包含空格

Qtopia的依赖和必要条件
——————————————————————————–
简介
为了使Qtopia正确运行, 必须满足以下的必要条件:
安装适当的编译/交叉编译工具
Qt/Embedded-2.3.11
Linux kernel提供共享内存、mmap和socket支持
Linux支持frame buffer
Linux支持OSS声音或支持与OSS兼容的ALSA声音。 进一步的信息参考 The Qtopia A/V & Appearance FAQ
还需要以下的库:

Video4Linux
zlib
libuuid(aka luuid)
libjpeg
xorg 或X11
注:Freetype不是必须的但建议支持 http://freetype.sourceforge.net/index2.html

支持的编译器和交叉编译器
gcc-2.95.2
gcc 3.2.4
gcc-3.3.0, gcc-3.3.3, gcc-3.3.4
gcc-3.4.1

声音

Qtopia需要/dev/dsp可写,并支持以下的ioctl操作:

SNDCTL_DSP_SETFRAGMENT – Qtopia将这个值设置为0x4000c.
SNDCTL_DSP_SETFM – Qtopia设置为AFMT_S16_LE
SNDCTL_DSP_STEREO – Qtopia 设置为 1/true.
SNDCTL_DSP_SPEED – Qtopia设置为44100.
SNDCTL_DSP_GETOSPACE
Qtopia 还需要/dev/dsp可以以阻塞方式和非阻塞方式打开。以上的设定是Qtopia需要的设定,但可以容许少许的偏差,但如果不设定成Qtopia需要的值则不能保证音频能平滑播放。假如您的设备只支持22500的播放速率,则在调用SNDCTL_DSP_SPEED时要报告此速率,以免造成音频质量的缺损。不过,如果系统不支持GETOSPACE,非阻塞写入或 SNDCTL_DSP_SET_FRAGMENT, 几乎可以肯定必然会损失音频质量。

Video4Linux

Camera应用程序需要支持Video4Linux v1的内核, Qtopia没有提供该支持。

请参考官方的 Video for Linux 资源站点,参看API的详细内容。

zlib

zlib可以从 http://www.gzip.org/zlib/ 下载

libuuid(aka luuid)

Qtopia不提供uuid支持。 这个库可以从 http://e2fsprogs.sourceforge.net/ 站点下载

另外, 如果你有SuSE Linux的发行版, e2fsprogs-devel这个包可以提供uuid支持; 在Debian中对应的包是uuid-dev. 这个库应该放在标准路经下/usr/lib/libuuid.so

请用包管理工具来查看该包是否已经安装:

rpm -qa | grep e2fsprogs

如果尚未安装,请从安装盘或镜像站安装这个包。

需要注意的是,如果没有安装e2fsprogs-devel,在链接时会发生下面的错误:

/usr/lib/gcc-lib/i586-suse-Linux/3.3.3/../../../../i586-suse-linux/bin/ld:
cannot find -luuid
如果安装了该库仍遇到上述错误,则检查Qtopia的configure脚本的-L和-R参数, 以确定脚本包含了库的实际路径。 关于交叉编译的信息可参考 System Integrator’s Guide.

libjpeg

Qtopia不提供jpeg库。 Qtopia需要Qt/Embedded配置为支持jpeg。

libjpeg库可从 http://www.ijg.org/ 下载

此外,如果你有SuSE发行版, libjpeg这个包可提供该库。 这个库应该安装在标准路经/usr/lib/libjpeg.so

检查libjpeg包是否已经安装:

rpm -qa | grep libjpeg

如果未安装,请从安装盘或镜像站安装。

关于libjpeg交叉编译的信息, 可参考System Integrator’s Guide.

xorg或X11

开发包括有从以下站点下载:

http://www.xfree86.org/
http://xorg.freedesktop.org
相关讨论

决定开始Qtopia需要的步骤, 参考: Getting started

将Qtopia集成到特定设备上的重点步骤, 参考: System Integrator’s guide

Qtopia的FAQs,参看: Qtopia index page

系统是完全安装RedHat9.0(里面带QT3.1),板子是X-Hyper250B的,Toolchain用的是开发板带的hybus-arm-linux-R1.1

交叉编译所用到的文件:
qt-embedded-2.3.10-free.tar.gz
qt-x11-2.3.2.tar.gz
qtopia-free-source-2.1.1.tar.gz
tmake-1.13.tar.gz
e2fsprogs-1.35.tar.gz

主机x86的编译步骤:
tar xfz qt-embedded-2.3.10-free.tar.gz(解压后qt-2.3.10改名为qt-2.3.10-host)
export QTEDIR=$PWD/qt-2.3.10-host
tar xfz qt-x11-2.3.2.tar.gz(解压后qt-2.3.2)
export QT2DIR=$PWD/qt-2.3.2
tar xfz qtopia-free-source-2.1.1.tar.gz(解压后qtopia-free-2.1.1改名为qtopia-2.1.1-host)
export QPEDIR=$PWD/qtopia-2.1.1-host
tar xfz tmake-1.13.tar.gz(解压后tmake-1.13)
export TMAKEDIR=$PWD/tmake-1.13
export TMAKEPATH=$PWD/tmake-1.13/lib/qws/linux-x86-g++
export PATH=$TMAKEDIR/bin:$PATH

cd qt-2.3.2
export QTDIR=$QT2DIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure -no-xft
make
make -C tools/qvfb
cd ..

cd qt-2.3.10-host
export QTDIR=$PWD
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
mkdir bin (因为解压后的qt-2.3.10没有bin文件夹)
cp $QT2DIR/bin/uic bin
cp $QT2DIR/tools/qvfb/qvfb bin
cp $QPEDIR/src/qt/qconfig-qpe.h src/tools/
./configure -qconfig qpe -qvfb -thread -system-jpeg -gif -depths 4,8,16,32
make
cd ..

tar xzf e2fsprogs-1.35.tar.gz
cd e2fsprogs-1.35
./configure -enable-elf-shlibs
make install lib/uuid/
注:这是编译x86的libuuid库
cd ..

cd qtopia-2.1.1-host
export PATH=$QPEDIR/bin:$PATH
export LD_LIBRARY_PATH=$QPEDIR/lib:$LD_LIBRARY_PATH
./configure
make

编译例子:
$qmake -project ==>>我都是这样创建.pro文件的
$tmake -o Makefile hello.pro
$make
$qvfb &
$./hello -qws 或者$qpe
还没怎么仔细研究过。

目标机arm-linux的编译步骤:
tar xfz qt-embedded-2.3.10-free.tar.gz(解压后qt-2.3.10改名为qt-2.3.10-target)
export QTEDIR=$PWD/qt-2.3.10-target
tar xfz qt-x11-2.3.2.tar.gz
export QT2DIR=$PWD/qt-2.3.2
tar xfz qtopia-free-source-2.1.1.tar.gz(解压后qtopia-free-2.1.1改名为qtopia-2.1.1-target)
export QPEDIR=$PWD/qtopia-2.1.1-target
tar xfz tmake-1.13.tar.gz
export TMAKEDIR=$PWD/tmake-1.13
export TMAKEPATH=$PWD/tmake-1.13/lib/qws/linux-arm-g++
export PATH=$TMAKEDIR/bin:$PATH

cd qt-2.3.2
export QTDIR=$QT2DIR
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
./configure -no-xft
make
make -C tools/qvfb
cd ..

cd qt-2.3.10-target
export QTDIR=$PWD
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
mkdir bin
cp $QT2DIR/bin/uic bin
cp $QT2DIR/tools/qvfb/qvfb bin
cp $QPEDIR/src/qt/qconfig-qpe.h src/tools/
./configure -xplatform linux-arm-g++ -qconfig qpe -qvfb -thread -system-jpeg -gif -depths 4,8,16,32
make
cd ..
注:这里需要arm版本的libjpeg.so.62,hybus-arm-linux-R1.1里面包含这个库;如没有可以上网下载。

tar xzf e2fsprogs-1.35.tar.gz
cd e2fsprogs-1.35
./configure -host=arm-linux -with-cc=arm-linux-gcc -with-linker=arm-linux-ld -enable-elf-shlibs -prefix=/usr/local/hybus-arm-linux-R1.1/arm-linux
make install lib/uuid/ ===>>>这步安装到hybus-arm-linux-R1.1/lib上的libuuid.so.1.2版本不对,
要cp lib/libuuid.so.1.2 ../hybus-arm-linux-R1.1/lib
注:这步是交叉编译arm的libuuid库,配置详情见./configure –help
(还要多谢 http://panjet.wleda.com/?p=20 这里面的大哥呀,好不容易才在网上找到的)
cd ..

cd qtopia-2.1.1-host
export PATH=$QPEDIR/bin:$PATH
export LD_LIBRARY_PATH=$QPEDIR/lib:$LD_LIBRARY_PATH
cp src/libraries/qtopia/custom-linux-ipaq-g++.cpp src/libraries/qtopia/custom-linux-arm-g++.cpp
cp src/libraries/qtopia/custom-linux-ipaq-g++.h src/libraries/qtopia/custom-linux-arm-g++.h
./configure -xplatform linux-arm-g++
make
注:这里需要libstdc++.so和libgcc_s.so库

develop环境下qt中文化程序设计
——————————————————————————–
原文出处:Linux公社

kdevelop是一款在linux平台下可以同windows环境下的vc相媲美的集成开发环境,qt则是一款支持包括windows和linux平台
的GUI库,可以说它是linux下的MFC.在显示上,qt使用Unicode作为内部编码,可以支持多种编码.如何使用qt进行国际化编程
在网上可以找到很多资料的,但都是针对较早版本的qt进行介绍的.qt3.0.5中对这些作了些改动,这些方法就相应的要做些改动.
而且在kdevelop中开发qt应用程序,将会事半功倍.我的开发环境为redhat8.0(需安装kde开发工具包).
首先在linux中打开kdevelop集成开发环境,用它的应用程序向导新建一个qt的SDI的应用程序框架.这个同windows下vc很类似.它
将会为你自动生成版本号,作者,e-mail等信息的单文档对话框的应用程序框架.我们首先对它自动生成的程序进行汉化(qt1是
我的项目名称).

1.汉化自动生成的程序

添加翻译文件
在”项目”菜单中选择”添加新的翻译文件”,语言选择”zh_CN.Gb2312″.将会创建一个zh_CN.GB2312字符编码的翻译文件.扩展名
为”.ts”.在qt3.0.5环境下,打开”*.ts”翻译文件的工具是linguist.你可以在”工具”菜单中选择”QT
linguist”来打开,在linguist菜单中选择”file”->”open”打开所要翻译的翻译文件.此时可以在linguist窗口中的source text中
的文本就是你所要翻译的文本,选择所要翻译的文本,在下方有一个类似一页纸一样的地方,在translate下输入翻译后的文本.所示.
翻译完这些文件后,编译运行,在我们的程序里并不能显示中文,还是英文,我们还需要做的就是用lrelease命令将翻译后的文件转换成”.qm”文件才可以使用.在控制台下进入你用kdevelop所生成的应用程序目录.
>lrelease Makefile.am
qt3.0.5用这个两个程序取代了以前版本的findtr和msg2qm命令.在kdevelop集成环境中打开main.cpp主函数,
……
QApplication a(argc, argv);
a.setFont(QFont(“helvetica”, 10));
QTranslator tor( 0 );
tor.load( QString(“qt1.”) + QTextCodec::locale(), “.” );
// tor.load( QString(“qt1.zh_CN.GB2312”), “.” );
a.installTranslator( &tor );
/* uncomment the following line, if you want a Windows 95
look*/
// a.setStyle(WindowsStyle);

Qt1App *qt1=new Qt1App();
//Form1 *qt1=new Form1();
a.setMainWidget(qt1);
……
此处:
tor.load( QString(“qt1.”) + QTextCodec::locale(), “.” );
是根据客户环境的locale来载入当前目录下相应的翻译文件的.redhat中文环境默认的locale为gb18030,
此处要么把翻译文件名由qt1.zh_CN.GB2312.qm改为qt1.zh_CN.GB18030.qm,要么将这句改为
tor.load( QString(“qt1.zh_CN.GB2312”), “.” );
不过为了国际化编程的需要,建议采用第一种方法.更改后编译运行,你会发现你的程序已经是中文界面的了.

2.汉化自己的对话框

大多数情况下我们都需要自己来设计对话框,qt为我们提供了非常好的对话框编辑器QtDesigner,可以很方便的设计我们的对话框,qt
的信号和槽等,关于QtDesigner的使用,限于篇幅,不再赘述.以前面的程序为基础.在kdevelop中选择”文件”->”新建”,选择Qt
Designer文件(*.ui).在文件名一栏中填写”mydialog”,最后点击确定按钮,即会启动QtDesigner,此处只拖了一个Label,写了一
些英文字符.对话框的name属性为Form1.将对话框mydialog.ui保存.
在控制台下进入你用kdevelop所生成的应用程序目录.
>lupdate Makefile.am
同样用”QT
linguist”来翻译qt1.zh_CN.GB2312.tr文件.此时linguist的context中会多出Form1的选项,这里面就是我们新建的对话框要翻译的
选项.依据前面的方法进行汉化.
>lrelease Makefile.am
生成qt1.zh_CN.GB2312.qm文件.
编译将会生成mydialog.cpp mydialog.h mydialog.moc文件.然后将main.cpp中的
Qt1App *qt1=new Qt1App();改为
Form1 *qt1=new Form1();
并将”mydialog.h” #include
进去.依据前面的方法更改tor.load中加载的翻译文件.编译运行,你的对话框也是中文的了.

3.其它的一些说明

由于qt返回的是Unicode编码,譬如你在LineEdit中直接输入中文,返回的就是??,qt中可以直接使用QTextCodec来转换字符串的编码.
QString string;
string=LineEdit1->text(); //取得LineEdit1返回的文字
QTextCodec *codec=QTextCodec::codecForName(“GBK”);
//转换编码
QCString
chinese_string=codec->fromUnicode(string);//用QCString来存储返回的多字节编码
当然,你在头文件中就必需加入
#include <qtextcodec.h>
#include <qstring.h>
#include <qcstring.h>

4.QTextStream对中文的支持

QTextCodec* codec = QTextCodec::codecForName(“GBK”); /* 当前编码为”GBK” */
QTextStream mystream(&file);
mystream.setCodec(codec);

5. QCString&QString
QCString中不以unicode编码
QString以unicode为编码.
qt内部使用unicode为编码,所以如果要在qt的部件如multilineedit中显示中文,则需要将非unicode的字符转换成unicode字符.
QCString locallyEncoded = “中国人不是东亚病夫”; // text to convert
QTextCodec *codec = QTextCodec::codecForName(“GBK”); // get the codec for GBK
QString unicodeString = codec->toUnicode( locallyEncoded );

http://www-128.ibm.com/developerworks/cn/l…oolkit/qt/i18n/

Qt 国际化编程
——————————————————————————–
内容:

1. Qt 的文本显示

2. Qt 的文本输入

3. Qt 的打印

于明俭

2002 年 1 月 09 日

本篇讨论 Qt 库对国际化的支持,将介绍 Qt 对文本显示,输入和打印的支持,和如何 使用Qt 开发国际化的软件。
Qt 目前的版本(2.2.4)对国际化的支持已经相当完善。 在文本显示上,Qt 使用了Unicode 作为内部编码,可以同时支持多种编码。 为 Qt 增加一种编码的支持也比较方便,只要 增加该编码和Unicode的转换编码便可以了。 Qt 目前支持ISO标准编码ISO 8859-1, ISO 8859-2,ISO 8859-3,ISO 8859-4,ISO 8859-5,ISO 8859-7,ISO 8859-9,和 ISO 8859-15(对于阿拉伯语和希伯来语的支持正在开发之中),中文GBK/Big5,日文 eucJP/JIS/ShiftJIS,韩文eucKR,俄文KOI8-R。 当然也可以直接使用UTF8编码。

Qt 使用了自己定义的Locale机制,在编码支持和信息文件(Message File)的翻译上弥补了目前Unix上所普遍采用Locale和gettext的不足之处。 Qt 的这种机制可以使 Qt 的同一组件(QWidget)上同时显示不同编码的文本。 比如,Qt 的标签上可以同时使用中文简体 和中文繁体文本。

在文本输入上,Qt 采用了XIM(X Input Method)标准协议,可以直接使用XIM输入服务器。由于目前的绝大多数输入服务器都是针对单一语言的,所以在 Qt 的标准输入组件( QLineEdit,QMultiLineEdit)中的输入受到单一编码的限制,Qt 还不支持动态切换编码输入的支持,这是它的不足之处。

1. Qt 的文本显示
——————————————————————————–
像普通的国际化过程一样,Qt 使用了类似GNU gettext一样的函数 QObject::tr(),它 用于从Qt的信息文件 .qm 中取出信息,这些信息是经过 Qt 的工具处理的。 Qt在处理 编码时还使用了 QTranslator 类,可用于指定整个应用软件的 的信息文件。

使用 Qt 编写国际化的程序,最好不要在程序中直接使用特殊编码的文本。 比如要 编写一中文界面的 Qt 程序,应该在程序中使用英文,程序编写完成后,把文本提取 出来翻译。 这样,程序还可以根据Locale的不同,支持多种语言。 下面介绍如何在 Qt 程序中标注字符串,如何提取并翻译文本。
下面是一段使用了 QObject::tr()的代码,它建立了一个弹出菜单,菜单项是”Quit”, 它被放置在菜单条上,在菜单条上显示的是标签”File”。

QPopupMenu* popup;
popup = new QPopupMenu( this );
popup->insertItem( tr(“&Quit”),qApp,SLOT(quit()) );
menubar->insertItem( tr(“&File”),popup );

对于绝大多数情况,可以用上述方法处理。不过有时在定义某些变量中使用的字符串,不能使用上述方法,但是为了让Qt提取并翻译该字符串,必须用某种方法标志出 来。Qt 定义了 QT_TR_NOOP() 和 QT_TRANSLATE_NOOP() 来标志它们。前者用于单个字符串,后者用于多个字符串。比如,

static const char* strings[] = {
QT_TR_NOOP( “Hello” ),
QT_TR_NOOP( “World” )
};

有时需要使用printf/sprintf之类的函数动态生成字符串,比如,

QStings s;
s.sprintf( “Button %d”,i );
but->setText( s );

对这种使用方式的国际化是使用 arg() 函数。

QString s = tr( “Button %1” ).arg(i);
but->setText( s );

提取上述信息的方法是使用 Qt 提供的工具 findtr 命令:

findtr [filename].cpp > i18n.po

它类似于GNU的 xgettext,上述文件的提取信息文件内包含,

….
“Content-Type: text/plain; charset=iso-8859-1\n”

#: i18n.cpp:34
msgid “ExampleWidget::&File”
msgstr “”

接下来是文本翻译过程。 在Qt中翻译信息文件时应该注意以下事项: (1) 提取的信息文件的编码是iso-8859-1,在翻译成某种语言(编码)时应该 注意改动它的字符集,比如对中文GB2312和Big5编码,应该是, “Content-Type: text/plain; charset=gb2312\n”或者”Content-Type: text/plain; charset=big5\n”。 (2) 提取的信息有一个范围,比如上面的文件指定的范围是 ExampleWidget, 在翻译 前应该把它去掉,变成 msgid “::&File”。(3) 被翻译的字符串可能含有加速键符号,如 “&File”中的”F”,如果翻译成中文最好保留该信息,它可以翻译成 “文件(&F)”。

对于翻译后的文件(比如上面的翻译文件存为 i18n_gb.po),必须使用 Qt 提供的 工具 msg2qm 把它转换为 .qm 文件才能使用,

> msg2qm i18n_gb.po i18n_gb.qm

它类似于GNU的 msgfmt 命令。翻译后的文件可以用Qt程序直接调用。

QTranslator *translator = new QTranslator(0);
translator->load(“i18n_gb.qm”,”.”);
qApp->installTranslator(translator);

此外,Qt 还提供了类似于 msgmerge 的工具 mergetr,它用于把新提取的信息 文件和已经翻译过的信息文件融合起来,在此不再赘述。

在 Qt 中也可以直接使用 QTextCodec 来转换字符串的编码,这为在Qt下开发纯 中文软件带来了便利条件,不过这种方法不符和国际化/本地化的习惯,

char *string = “中文和English混和字符串!”
QTextCodec* gbk_codec = QTextCodec::codecByName(“GBK”);
QString gbk_string = codec->toUnicode(string);
QLabel *label = new QLabel(gbk_string);

如果使程序只支持一种编码,也可以直接把整个应用程序的编码设置为GBK编码, 然后在字符串之前 加tr(QObject::tr),

qApp->setDefaultCodec( QTextCodec::codecForName(“GBK”) );
QLabel *label = new QLabel( tr(“中文标签”) );

如果使Qt根据Locale的环境变量取得字符集,可以使用 QString::fromLocal8Bit(str)。

本节的例子请参见 qt-i18n-example.tar.gz

2. Qt 的文本输入
——————————————————————————–
在输入方面,Qt 的输入条(QLineEdit)和编辑区(QMultiLineEdit)都支持 XIM,只要配合相应的输入服务器,便可以输入中文/日文/韩文。目前有许多支持XIM的软件,比如 中文: Chinput/xcin/rfinput/q9,日文: kinput2/skkinput,韩文: ami/hanIM。

Qt程序的缺省输入风格是OverTheSpot风格,它也支持 OffTheSpot风格和 Root风格。 用户可以在起动程序时在命令行指定输入风格,比如对程序app,

./app -inputstyle overthespot #缺省风格,光标跟随
./app -inputstyle offthespot
./app -inputstyle root

经过 MiziLinux 补丁的Qt-2.2.0 支持 OnTheSpot 输入风格,并且把它作为 缺省的输 入风格。请参见 http://www.mizi.com/ko/kde/doc/onthespot/onthespot.html。

Qt 中的任何一个 Widget 都可以接受输入,只要它可以有键盘聚焦(Keyboard Focus)。所以对特殊 Widget 的输入处理只需要截获键盘输入,获取从XIM服务器 来的字符串。 对于OverTheSport风格的支持,刷新XIM输入服务器的位置即可。

3. Qt 的打印
——————————————————————————–
在打印方面,XWindow下的 Qt 生成PostScript并使用lpr打印。 它含有QPrinter类, 可以方便地支持输出页面的控制。 对于中文打印,必须修正PostScript文件的输出 部分。

TOpia中文化
——————————————————————————–
一:字符集介绍

我国已经颁布了多种中文信息编码标准,常用的有:GB2312-1980、GB12345、GB13000(GBK)以及最新标准GB18030,其中 GB13000是对GB2312的扩展,又常被成为GBK,GB18030向下兼容GB2312和GBK,中文WINDOW98、中文WIN2000操作系统采用的中文字符集是GB2312。

GB2312字库仅覆盖双字节部分,存储位置索引是编码中每字节的第8bit置0得来的,如A1A1编码汉字在字库中的索引是2121,而非A1A1。以下是它的编码规则:

单字节:00~7F

双字节:A1~F7 A1~FE

GBK的编码规则是:

单字节:00~7F

双字节:81~FE 40~7E

80~FE

GB18030是最新的汉字编码标准,其编码为一、二、四变长编码:

单字节:00~7F

双字节:81~FE 40~7E

80~FE

四字节:81~FE 30~39 81~FE 30~39

Unicode编码采用等长编码,二个字节表示一个字符编码,对于ASCII码也采用双字节来表示,unicode使用二维空间来描述编码空间,平面分为256行、256列,对应于编码的高低字节。

二:Qt 国际化编程

在文本显示上,Qt 使用了Unicode 作为内部编码,为了程序的国际化,通常我们在文本显示的地方不直接输入本地字符,用英文代替,比如要编写一中文界面的 Qt 程序,应该在程序中使用英文,程序编写完成后,把文本提取出来翻译。对于需要翻译的地方,首先是在该文本处用tr()函数标识,同时制作出.qm信息文件,并在程序中加入QTranslator即可。比如我们在某一程序中有如下语句:

setCaption(tr(“main window”));

为了能显示中文,有两种方法:

方法一:
——————————————————————————–
修改工程文件,加上TRANSLATIONS = xxx.ts

lupdate 工程文件名

用linguist编辑刚生成的xxx.ts文件并保存

lrelease 工程文件名 xxx.qm

在main.cpp中加入QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);

qApp->setFont(font1);

QTranslator *translator = new QTranslator(0);
translator->load(“xxx.qm”,”.”);
qApp->installTranslator(translator);

方法二:
——————————————————————————–
findtr 文件名(通常为CPP文件) > xxx.po

编辑po文件,其中charset需由iso-8859-1改为GB2312,然后将“main window”翻译成“主窗口”

msg2qm –scope zh_CN.GB2312 xxx.po xxx.qm

在main.cpp中加入QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);

qApp->setFont(font1);

QTranslator *translator = new QTranslator(0);
translator->load(“xxx.qm”,”.”);
qApp->installTranslator(translator);

方法三:
——————————————————————————–
有时我们只是提供给本地用户使用,无需国际化,QT提供这一支持,在QT中有许多本地字符集同unicode的转换引擎,他们皆为QTextCodec的派生类,如QGbkCodec、QJisCodec, QHebrewCodec等。如:

QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);

qApp->setFont(font1);

QString caption=“主窗口“;

QTextCodec *gk_codec=QTextCodec::codecForName(“GBK”);

setCaption(gk_codec->toUnicode(caption));

从上面可以看出,使用转换引擎可以轻松实现中文显示,简要步骤如下:

1:修改main.cpp文件,将字体改为unifont

QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);

qApp->setFont(font1);

2:在想汉化的内的头文件中加入QTextCodec指针变量和转换函数QString mytr(char *)

#include <qtextcodec.h>

QTextCodec* gbk;

QString mytr(const char *);

3:在想汉化的类的实现文件中,修改类构造函数,加入:

gbk=QTextCodec::codecForName(“GBK”);

4:在想汉化的类的实现文件中,添加mytr函数代码

QString Form1::mytr(const char* chars)

{

return gbk->toUnicode(chars,strlen(chars));

}

5:在想汉化的类的实现文件中,用“mytr”替换“tr”

2004-12-2 测试了上面的方法三,编译通过,如果将codec成员变量改成QTextCodec派生类变量,编译将通不过,比如将QTextCodec* gbk;改成QGbkCodec* gbk;编译将报告此处有语法错误。下面是相似的用法:

1:修改***.cpp文件,在顶部加入codec头文件

#include <qgbkcodec.h>

2:在***.h文件中,加入mytr()函数声明

QString mytr(char* buffer,int size);

3:在***.cpp文件中,加入mytr()定义

QString mytr(char* buffer,int size)

{

QGbkCodec* gbk=QTextCodec::codeForName(“GBK”);

return gbk->toUnicode(buffer,size);

}

4:在需要显示中文的地方,使用mytr函数即可

5:修改main.cpp文件,将字体改为unifont

QFont font1(“unifont”,16,50,FALSE,QFont::Unicode);

qApp->setFont(font1);

备注:在翻译或转换之前必须将Unicode字体调入,否则显示不出中文,网上相关文章并未提及这一点,如果不显式装载该字体,系统默认的是Latin1,于是汉字显不出来。

备注2:在编译qt/embedded之前,必须修改qconfig-qpe.h配置文件的内容,将与TextCodec相关的宏定义给去掉,否则QTextCodec::codecForName(“GBK”)将返回NULL指针。

备注3:使用findtr命令时可同时查找多个文件的tr(),并将查找结果都放入一个文件内,源文件以空格隔开即可,另外,生成的.po和.qm文件的文件名最好与工程文件名相同!

备注4:如果要显示繁体中文,则需要使用QTextCodec::codecForName(“big5”)。获取本地的使用语言,用 QTextCodec::locale(),它返回Qstring变量,通常如果是中文本地的话,通常其值为zh_CN.GB2312和 zh_TW.Big5,根据这个返回字符串,可以加载相应的codec。如果程序只支持一种编码,也可以直接把整个应用程序的编码设置为一个默认的编码标准,比如系统只需要显示中文和英文,则可以直接设置应用程序的默认编码标准是GBK,如下使用方法:

qApp->setDefaultCodec( QTextCodec::codecForName(“GBK”) );

QLabel *label = new QLabel( tr(“中文标签”) );

备注5:如果使用本地的字符转换器,可以使用Qstring的静态函数Qstring::fromLocal8Bit(char* buffer,int size),将本地字符串转换成UNICODE字符串,不过要设置好LANGUAGE环境变量。

三:QTOpia中文化
——————————————————————————–
findtr 文件名 > xxx.po

编辑xxx.po文件

msg2qm –scope zh_CN.GB2312 xxx.po xxx.qm

拷贝可执行文件到QPEDIR/bin目录

拷贝xxx.po和xxx.qm文件到QPEDIR/i18n/zh_CN目录

进入QPEDIR/apps/Applications目录创建一新.desktop文件

iconv –f utf8 –t GB18030 xxx.desktop > xxx1.desktop

编辑xxx1.desktop文件,主要是修改Exec、Icon、Name和Name[zh_CN]四项

iconv –f GB18030 –t utf8 xxx1.desktop > xxx.desktop

rm –f xxx1.desktop

qvfb –depth 16 &

cd $QPEDIR/bin

./qpe

备注:如果你的系统中有多个qtopia版本,要特别注意QTDIR、QPEDIR、LD_LIBRARY_PATH环境变量

备注2:可按照此方法汉化qtopia自带的应用程序

备注3:po文件是中间文件,程序真正需要的是qm文件。iconv是系统自带的内码转换工具,它能将utf8编码的文件转换成gb18030编码的文件,反之也能,转换这一步必不可少,因为desktop文件缺省是utf8编码的,而我们的redhat linux 7。3中文操作系统用的却是gb18030,所以在编辑器打开前需转换。

四:汉化qtopia-1.5.0 for Arm
——————————————————————————–
首先按照“三”的方法对要汉化的程序提取*.qm文件和*.desktop桌面配置文件,在做完这一步后,将*.qm文件down到目标机的 /opt/qtopia-free-1.5.0.arm/i18n/zh_CN目录下,同时将*.desktop文件覆盖/opt/qtopia- free-1.5.0.arm/apps目录下的相应文件,目标机的环境变量配置如下:

export QTDIR=/opt/qt-2.3.3.arm

export QPEDIR=/opt/qtopia-free-1.5.0.arm

export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

export PATH=$QPEDIR/bin:$PATH

export LANG=zh_CN

开机启动,由于设置的语言为简体中文,qpe会自动为每个应用加载Unifont字体,以及简体中文目录下的翻译文件,因而显示出中文,翻译文件是一个方面,但更关键的是要显示中文必须有中文字体来支持,Unifont字体包含中文字,因而能显示中文,没有相应字体的支持,光有翻译文件是显示不出中文的!

在经过以上的步骤后,有的应用在显示上依然会显示方框,这多半是由于该窗体相关的字体可能不是支持中文的字体,这需要直接修改源代码,以下是在汉化qtopia-free-1.5.0.arm的过程中的相关记录:

1. 在编译qtopia的过程中,可能会报告找不到SetButtonGroupID()函数,编译通不过。这是由于库中并没有该函数,一般情况下将该语句隐藏掉,原代码的原意是设置Button按钮在ButtonGroup组的序号,隐藏该语句对应用无影响。出现这个问题,主要在 /netsetup/dialup/dialupbase.cpp文件和/taskbar/shutdown.cpp文件,shutdown.cpp文件的相应行号是:96、149、201、253行。

2. 修改mpegplayer/playlistwidget.cpp文件的143行和166行,将字体设置改为Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句

3. 修改snake/interface.cpp的87行和186行,将字体设置改为Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句

4. 修改qasteroids/view.cpp的104行和qasteroids/toplevel.cpp的109行和165行,将字体设置改为 Unifont,如下:Qfont(“unifont”,16,50,FALSE,QFont::Unicode)或者去掉该语句

5. 修改sysinfo/versioninfo.cpp文件,将61行的builder改为作者本人,将50行的v改为tr(“corpname”),重新建立po文件,并翻译corpname为 您希望的名字,使用msg2qm生成qm文件

6. 修改桌面,位于taskbar目录下,生成libqpe.po和libqpe.qm文件,并将libqpe.qm文件拷贝到i18n/zh_CN目录下

五:qtopia目录结构
——————————————————————————–
apps/Applications:应用程序桌面配置文件

apps/Games:游戏桌面配置文件

apps/Settings:系统设置桌面配置文件

bin:二进制可执行文件

configs:编译配置文件目录

doc和docs:qtopia的参考文档

etc:应用配置文件目录

i18n:国际化目录

i18n/zh_CN:简体中文目录

include/qpe:与qtopia相关的头文件目录

inputmethods:输入法

library:qtopia部分源代码目录

pics:与应用相关的图片存放目录

plugins:各种插件目录,如mpeg3解码插件、输入法插件等

sounds:音频文件存放目录

taskbar:桌面程序的源代码(qpe的源代码)

Gtk与Qt编译环境安装与配置

Posted by – December 13, 2009

http://wiki.ubuntu.org.cn/Gtk%E4%B8%8EQt%E7%BC%96%E8%AF%91%E7%8E%AF%E5%A2%83%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE#.E5.AE.89.E8.A3.85QT3.2FKDE3.E5.BC.80.E5.8F.91.E7.8E.AF.E5.A2.83

QT资源

Posted by – December 10, 2009

http://lfs.linuxsir.org/htdocs/blfscvs/x/qt.html

STL 简介(标准模板库 简介)

Posted by – December 10, 2009

STL 简介,标准模板库 简介:
http://www.linuxsir.org/bbs/thread44097.html