Chinaunix首页 | 论坛 | 博客
  • 博客访问: 202211
  • 博文数量: 50
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 583
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-12 14:38
文章分类

全部博文(50)

文章存档

2013年(50)

我的朋友

分类: LINUX

2013-04-22 08:03:59

原文地址:qt移植解惑 作者:sjj0412

------------------------------------------------
本文系本站原创,欢迎转载!

转载请注明出处:http://sjj0412.cublog.cn/
------------------------------------------

Qt是一个多平台的C++图形用户界面应用程序框架。它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt是完全面向对象的很容易扩展,并且 允许真正地组件编程。

()首先我们来讲下我们安装qt的原因:

    我们平常在编写程序用的最多的是什么?

      也许你会答些代码,这个当然是,但是有一个很重要的东西是

       使用#include

我们为什么使用include,因为我们想使用printf,fork,malloc等这些函数,

其实说白了就是使用别人写好的东西,以减少自己的代码量,这就是库的作用。

其实我们安装qt其实就是安装库及头文件。

   当然如果我们想要更好的开发环境,就会希望有像vc那种可视化的开发工具,这些都是qt安装时生成,这也是为什么需要安装qt的原因。

 

(二)下面就进一步讲下一些概念:

首先让我们来了解下一些概念:

 qt-x11

 qt-embeded

 qtopia

qt由于是跨平台的,故其能够在linux,window,mac等操作系统下运行。

既然是跨平台的,它就要将GUI分层,分成和平台相关的,及同平台无关的,所以当我们要安装qt时,就要针对具体平台下载具体平台的qt.

      在Linux,由于Linux广泛使用的是xwindow协议,所以qt-x11也要依赖xwindow,这样当我们要在linux pc上安装qt时,就要有xlib的相关库,也许你会说ubuntu的桌面是gnome,而gnome是基于gtk,而gtk又是在glib上扩展,glib又是xlib封装,那ubuntu应该就有xlib的相关库了吧,非也,glib是glib,xlib是xlib,他们的接口都不一样,你让qt怎么使用xwindow的相关东西(函数),也许你还会说那为啥qt不直接使用glib,而是使用xlib,其实这个很好理解,因为qt其实是和gtk等价的东西,你让他 gtk使用一样的继承关系glib,那未免不好,再说xlib是最基本的基础,用他可以更好的实现跨平台,否则,就算是在Linux下,如果一个用gtk,一个用xwindox,那么qt都要进行改动。

 Qt-embeded大家光看单词就可看出是指嵌入式qt,其实说是嵌入式,也说大了,只能说是主要针对具有framebuffer的嵌入式操作系统,如果是其他操作系统,你要修改的东西就多了去了,那还不如使用更精炼一点的gui,像minigui等,不过后来的版本的支持性更好,可以支持更多的图形引擎。既然提framebuffer,大家也猜到了,如果再缩小范围,其实这个所谓的嵌入式就是指嵌入式中的linux,但是它为什么要分出个pc linux及嵌入式linux版本,主要是因为嵌入式系统中资源有限,使用framebuffer能更有效的使用资源,且开发简单很多。既然是嵌入式,它也就没使用xlib了,因为xwindow当初就是为了适用一台服务器,多个终端,然后客户窗口通过网络同服务器窗口通信并被管理,这个在嵌入式系统中根本用不上,所以就没使用xlib,当然可能还有很多其他原因,但是嵌入式版本使用的窗口管理系统还是c/s模式。

  Qtopia又是什么呢?qtopia其实可以看成是qt-embedded的扩展,他主要是实现了一个桌面,使得应用程序员开发更简单,同时也增加了一些组件。如果你使用qt开发一个桌面系统,你就要写一个应用程序,这个应用程序要实现像任务栏,桌面图标,ime像输入法顶层窗口,及应用管理的这些功能。而这些在qtopia中,他已经帮你实现了,你要做得是开发具体的应用程序,这样就为我们减少了很大的任务量。

(三)下面就进入qt安装。

 

1首先安装x11。

    刚才说了x11版本使用的是xlib底层窗体机制,所以我们要确保x11 lib存在,然后我们就可以直接编译qt/x11,运行。

  环境:PC所用 Linux系统版本:Ubuntu8.04

首先下载: 

Qt/Embedded版本:qt- embedded-linux-opensource-src-4.4.3

Qt/X11版本:qt-x11-opensource-src-4.4.3

然后解压:

 tar zxvf qt-x11-opensource-src-4.4.3 -C ~/opt/qt

cd ~/opt/qt

刚才说到在linux pc上的qt是基于xlib所以要保证xlib库的存在,如果不存在

使用sudo apt-get install libx11-dev

下载xlib同时我在编译的过程中也发现还需要xext也将他下载sudo apt-get install libxext-dev反正是在编译的过程中发现什么错误就看下如果是缺少库下载就是了。

然后配置。

由于是编译在pc上运行的库,配置非常简单

1  ./configure -prefix ~/opt/run/qt

2  make

3  make install

 

1条命令是做啥用的呢他其实就是生成makefile文件及生成用来编译qt源代码用的一些工具qmakeqmake是用来解释.pro文件然后生成makefile文件的其实他的作用像automake就是自动生成makefile文件。

    第二条命令就是生成lib及其他工具像designer,uic,等工具的

make install就是将libtooldoc复制到-prefix指定的文件夹。

2 make过程非常长大概12小时此时可以看看网页或出去玩下。

然后我们就可以测试了。

首先我们要添加环境变量,我们新建一个文件用来添加这些环境变量。

jimmy@jimmy-linux:~/opt/run/qt$ cat setenv.sh

 

export QTDIR=$HOME/opt/run/qt            //使的qmake生成makefile知道include,lib

                                         路径,同时还有mkspecs规则

export QTDEDIR=$QTDIR

    

export PATH=$QTDIR/bin:$PATH         //这使得qmake,uci等工具能够直接使用,而不用进入~/opt/run/qte

export LD_LIBRARY_PAHT=$QTDIR/lib:$LD_LIBRARY_PAHT

                                     //这个使得加载程序时能够正确找到qt库

jimmy@jimmy-linux:~/opt/run/qt$ source setenv.sh                            

//source的作用是使得上面的设置生效。

上面的注释不在setenv.sh文件里,这里只是为了说明。

然后自己写个简单的程序。

 

 1.#include

 

  2 #include

 

  3 int main( int argc, char **argv )

 

  4 {

 

  5 QApplication a( argc, argv );

 

  6 QPushButton hello( "Hello world!", 0 );

 

  7 hello.resize( 100, 30 );

 

 

  9 hello.show();

 

 10 return a.exec();

 

 11 }

 

 

jimmy@jimmy-linux:~/test/cppd$ ls

 

testb  test.cpp

 

jimmy@jimmy-linux:~/test/cppd$ qmake -project

 

jimmy@jimmy-linux:~/test/cppd$ ls

 

cppd.pro  testb  test.cpp

 

jimmy@jimmy-linux:~/test/cppd$ qmake

 

jimmy@jimmy-linux:~/test/cppd$ ls

 

cppd.pro  Makefile  testb  test.cpp

 

jimmy@jimmy-linux:~/test/cppd$ make

 

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I../../opt/run/qt/mkspecs/linux-g++ -I. -I../../opt/run/qt/include/QtCore -I../../opt/run/qt/include/QtCore -I../../opt/run/qt/include/QtGui -I../../opt/run/qt/include/QtGui -I../../opt/run/qt/include -I. -I. -I. -o test.o test.cpp

 

g++ -Wl,-rpath,/home/jimmy/opt/run/qt/lib -o cppd test.o  -L/home/jimmy/opt/run/qt/lib -lQtGui -L/home/jimmy/opt/run/qt/lib -L/usr/X11R6/lib -lXext -lX11 -lQtCore -lm -lrt -ldl -lpthread

 

jimmy@jimmy-linux:~/test/cppd$ ls

 

cppd  cppd.pro  Makefile  testb  test.cpp  test.o

 

jimmy@jimmy-linux:~/test/cppd$

.cppd

 

 

 



然后编译:

qt-embedded版本

  

          过程一样,只是configure要变

我们首先编译一个在仿framebuffer的版本,即生成的代码是针对pc的,用qvfb来模仿framebuffer,达到在宿机上开发目标机的程序并调试,这样当在宿机上运行成功时,再用交叉编译工具重新编译即可。

 .configure -prefix ~/run/qte -embedded x86 -qvfb

这样这个版本的qt就是以qvfb作为自己的显示设备。

  然后make,make install

同样我么调试由于这次我们要是使用qtembedded所以就要使用qt/embedded的库其实只需修改

QTDIR等环境变量即可。

jimmy@jimmy-linux:~/opt/run/qte$ cat setenv.sh

 

export QTDIR=$HOME/opt/run/qte

                                        //使的qmake生成makefile知道include,lib

                                         路径,同时还有mkspecs规则

export QTDEDIR=$QTDIR

    

export PATH=$QTDIR/bin:$PATH      //这使得qmake,uci等工具能够直接使用,而不用进入 ~/opt/run/qte

export LD_LIBRARY_PAHT=$QTDIR/lib:$LD_LIBRARY_PAHT

                                 //这个使得加载程序时能够正确找到qt库

jimmy@jimmy-linux:~/opt/run/qte$ source setenv.sh   

//source的作用是使得上面的设置生效。

 

x11时上面的目录是qt,现在是qte了。

然后我们再进入test目录,编译test.cpp

jimmy@jimmy-linux:~/test/cppd$ make clean

 

rm -f test.o

 

rm -f *~ core *.core

 

jimmy@jimmy-linux:~/test/cppd$ make

 

g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -I../../opt/run/qte/mkspecs/qws/linux-x86-g++ -I. -I../../opt/run/qte/include/QtCore -I../../opt/run/qte/include/QtCore -I../../opt/run/qte/include/QtNetwork -I../../opt/run/qte/include/QtNetwork -I../../opt/run/qte/include/QtGui -I../../opt/run/qte/include/QtGui -I../../opt/run/qte/include -I. -I. -I. -o test.o test.cpp

 

g++ -Wl,-rpath,/home/jimmy/opt/run/qte/lib -o cppd test.o    -L/home/jimmy/opt/run/qte/lib -lQtGui -L/home/jimmy/opt/run/qte/lib -lQtNetwork -lQtCore -lm -lrt -ldl -lpthread

 

jimmy@jimmy-linux:~/test/cppd$ ./cppd

 

QWSSocket::connectToLocalFile could not connect:: 没有该文件或目录

 

QWSSocket::connectToLocalFile could not connect:: 没有该文件或目录

 

QWSSocket::connectToLocalFile could not connect:: 没有该文件或目录

 

QWSSocket::connectToLocalFile could not connect:: 没有该文件或目录

 

QWSSocket::connectToLocalFile could not connect:: 没有该文件或目录

 

 

 

jimmy@jimmy-linux:~/test/cppd$

 

这时运行./cppd出错了,为什么,这就要提到我们前面说的,embedded版本下的qt也是采用c/s模式,所以必须要有server,由于没有server就出现了上面的错误,这时可能会问那为什么x11版本下没有server就可以运行呢。其实x11版本下也是有server,因为我们的pc linux gnome桌面系统也是基于xwindow的,所以在启动时就启动xwindow的服务器,这个就是X,正因为有了这个Xserver,x11版本下执行./cppd就可以了。

jimmy@jimmy-linux:~$ ps -aux |grep X

 

Warning: bad ps syntax, perhaps a bogus '-'? See

 

root      5902  5.2  4.9 109168 100060 tty7    Rs+  08:50   3:56 /usr/bin/X :0 -br -audit 0 -auth /var/lib/gdm/:0.Xauth -nolisten tcp vt7

 

jimmy     9182  0.0  0.0   3224   796 pts/5    S+   10:05   0:00 grep X

 

jimmy@jimmy-linux:~$

如果此时你sudo kill 5902,你将发现整个窗口程序没有了。

 那这个问题怎么解决呢,很简单,./cppd -qws,加个-qws就可以,这个是什么意思,这个就是说告诉qt,这个应用程序同时会作为server,所以会开启一个server,其源码实现是在

QApplication a( argc, argv );

构建qapplication是创建的,当construct发现参数有qws时就会开启一个server进程运行qwserver类的实例,并初始化。

让我们来看下代码实现,由于argv只传给了qapplication,应该可以看出在qapplication的构造函数里对argv进行了识别,事实上确实如此。

QApplication::QApplication( int &argc, char **argv )

{

    construct( argc, argv, GuiClient );

}

 

 

void QApplication::construct( int &argc, char **argv, Type type )

{

    qt_appType = type;

    qt_is_gui_used = (type != Tty);

    init_precmdline();

    static char *empty = (char*)"";

    if ( argc == 0 || argv == 0 ) {

       argc = 0;

       argv = ∅

    }

    qt_init( &argc, argv, type );   // Must be called before initialize()

    process_cmdline( &argc, argv );

 

#if defined(QT_THREAD_SUPPORT)

    qt_mutex = new QMutex(TRUE);

#endif

    

    initialize( argc, argv );

 

}

 

 void qt_init( int *argcptr, char **argv, QApplication::Type type )     {

...................

 else if ( arg == "-qws" ) {

           type = Qapplication::GuiServer;

...................

  if ( type == QApplication::GuiServer ) {

       qt_appType = type;

       qws_single_process = TRUE;

       QWSServer::startup(flags);//这个就会创建server

       setenv("QWS_DISPLAY", qws_display_spec, 0);

    }

}

QWSServer::startup(flags);//创建的server,qwsServer会指向它。

extern QWSServer *qwsServer; //there can be only one

 

现在让我们来看下。当然由于我们要使用qvfb仿真framebuffer,当然就要开启qvfb

这个时候就看到。

 

还有一点要注意的是:qt4不再有setmainwidget函数了。

 

下面是交叉版本的编译:

       其实交叉编译qte是差不多的,只是

./configure参数不一样:

        ./configure -prefix /home/jimmy/opt/run/qt-arm  -release -shared -fast -pch -no-qt3support -qt-sql-sqlite -no-libtiff -no-libmng -qt-libjpeg -qt-zlib -qt-libpng -qt-freetype -no-openssl -nomake examples -nomake demos -nomake tools -optimized-qmake -no-phonon -no-nis -no-opengl -no-cups -no-xcursor -no-xfixes -no-xrandr -no-xrender -no-xkb -no-sm -no-xinerama -no-xshape -no-separate-debug-info -xplatform qws/linux-arm-g++ -embedded arm -depths 16 -no-qvfb -qt-gfx-linuxfb -no-gfx-qvfb -no-kbd-qvfb -no-mouse-qvfb -qt-kbd-usb -confirm-license

后面一大堆参数,其实就是为了尽量减少库的大小,而剪裁一些不需要的功能。

      然后make

make install

      然后就是应用程序的交叉编译。

     这个时候要首先设置环境变量,这样

 1 export QTDIR=$HOME/opt/run/qt-arm

 

  2 export QTEDIR=$QTDIR

 

  3 export PATH=$QTDIR/bin:$QPEDIR/bin:$PATH

 

  4 export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

 

然后到新建一个文件main.cpp

qmake -project

qmake

make

即了

其实在第二步隐藏了一个细节qmake 等价于qmake -spec default,这个spec参数

就是到mkspecs文件夹找配置文件。

jimmy@jimmy-linux:~/opt/run/qt-arm$ ls

 

bin  include  lib  mkspecs  plugins  setenv.sh  tmake  translations

 

jimmy@jimmy-linux:~/opt/run/qt-arm$ cd mkspecs

 

jimmy@jimmy-linux:~/opt/run/qt-arm/mkspecs$ ls -l

 

总用量 336

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 aix-g++

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 aix-g++-64

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 aix-xlc

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 aix-xlc-64

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 common

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 cygwin-g++

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 darwin-g++

 

lrwxrwxrwx  1 jimmy jimmy   17 2009-05-05 15:28 default -> qws/linux-arm-g++

 

drwxr-xr-x  5 jimmy jimmy 4096 2009-05-05 15:28 features

 

drwxr-xr-x  2 jimmy jimmy 4096 2009-05-05 15:28 freebsd-g++

 

也就是说default其实是使用linux-arm-g++

jimmy@jimmy-linux:~/opt/run/qt-arm/mkspecs$ cd qws/linux-arm-g++/

 

jimmy@jimmy-linux:~/opt/run/qt-arm/mkspecs/qws/linux-arm-g++$ ls

 

qmake.conf  qplatformdefs.h

 

jimmy@jimmy-linux:~/opt/run/qt-arm/mkspecs/qws/linux-arm-g++$ cat qmake.conf

 

#

 

# qmake configuration for linux-g++ using the arm-linux-g++ crosscompiler

 

#

 

 MAKEFILE_GENERATOR    = UNIX

 

TEMPLATE        = app

 

CONFIG                    += qt warn_on release link_prl

 

QT                      += core gui network

 

QMAKE_INCREMENTAL_STYLE = sublib

 

 

 

QMAKE_CC             = arm-linux-gcc

 

QMAKE_LEX           = flex

 

QMAKE_LEXFLAGS             =

 

QMAKE_YACC        = yacc

 

QMAKE_YACCFLAGS         = -d

 

QMAKE_CFLAGS           = -pipe

 

QMAKE_CFLAGS_WARN_ON   = -Wall -W

 

QMAKE_CFLAGS_WARN_OFF =

 

QMAKE_CFLAGS_RELEASE      = -O2

 

QMAKE_CFLAGS_DEBUG   = -g

 

QMAKE_CFLAGS_SHLIB     = -fPIC

 

QMAKE_CFLAGS_YACC     = -Wno-unused -Wno-parentheses

 

QMAKE_CFLAGS_THREAD       = -D_REENTRANT

 

QMAKE_CFLAGS_HIDESYMS   = -fvisibility=hidden

 

 

 

QMAKE_CXX          = arm-linux-g++

 

QMAKE_CXXFLAGS            = $$QMAKE_CFLAGS

 

QMAKE_CXXFLAGS_WARN_ON    = $$QMAKE_CFLAGS_WARN_ON

 

QMAKE_CXXFLAGS_WARN_OFF   = $$QMAKE_CFLAGS_WARN_OFF

 

QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE

 

QMAKE_CXXFLAGS_DEBUG    = $$QMAKE_CFLAGS_DEBUG

 

QMAKE_CXXFLAGS_SHLIB      = $$QMAKE_CFLAGS_SHLIB

 

QMAKE_CXXFLAGS_YACC      = $$QMAKE_CFLAGS_YACC

 

QMAKE_CXXFLAGS_THREAD  = $$QMAKE_CFLAGS_THREAD

 

QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden

 

 

 

QMAKE_INCDIR            =

 

QMAKE_LIBDIR             =

 

QMAKE_INCDIR_X11   =

 

QMAKE_LIBDIR_X11    =

 

QMAKE_INCDIR_QT            = $$[QT_INSTALL_HEADERS]

 

QMAKE_LIBDIR_QT             = $$[QT_INSTALL_LIBS]

 

QMAKE_INCDIR_OPENGL  =

 

QMAKE_LIBDIR_OPENGL   =

 

QMAKE_INCDIR_QTOPIA   = $(QPEDIR)/include

 

QMAKE_LIBDIR_QTOPIA    = $(QPEDIR)/lib

 

 

 

QMAKE_LINK         = arm-linux-g++

 

QMAKE_LINK_SHLIB   = arm-linux-g++

 

QMAKE_LFLAGS           =

 

QMAKE_LFLAGS_RELEASE       =

 

QMAKE_LFLAGS_DEBUG   =

 

QMAKE_LFLAGS_SHLIB      = -shared

 

QMAKE_LFLAGS_PLUGIN     = $$QMAKE_LFLAGS_SHLIB

 

QMAKE_LFLAGS_SONAME     = -Wl,-soname,

 

QMAKE_LFLAGS_THREAD     =

 

QMAKE_RPATH             = -Wl,-rpath,

 

 

 

QMAKE_LIBS          =

 

QMAKE_LIBS_DYNLOAD      = -ldl

 

QMAKE_LIBS_X11         =

 

QMAKE_LIBS_X11SM   =

 

QMAKE_LIBS_QT          = -lqte

 

QMAKE_LIBS_QT_THREAD    = -lqte-mt

 

QMAKE_LIBS_QT_OPENGL       = -lqgl

 

QMAKE_LIBS_QTOPIA = -lqpe -lqtopia

 

QMAKE_LIBS_THREAD       = -lpthread

 

QMAKE_LIBS_OPENGL       =

 

 

 

QMAKE_MOC         = $$[QT_INSTALL_BINS]/moc

 

QMAKE_UIC            = $$[QT_INSTALL_BINS]/uic

 

 

 

QMAKE_AR             = arm-linux-ar cqs

 

QMAKE_OBJCOPY        = arm-linux-objcopy

 

QMAKE_RANLIB           = arm-linux-ranlib

 

 

 

QMAKE_TAR           = tar -cf

 

QMAKE_GZIP          = gzip -9f

 

 

 

QMAKE_COPY        = cp -f

 

QMAKE_MOVE              = mv -f

 

QMAKE_DEL_FILE        = rm -f

 

QMAKE_DEL_DIR          = rmdir

 

QMAKE_STRIP             = arm-linux-strip

 

QMAKE_CHK_DIR_EXISTS = test -d

 

QMAKE_MKDIR             = mkdir -p

 

load(qt_config)

 

jimmy@jimmy-linux:~/opt/run/qt-arm/mkspecs/qws/linux-arm-g++$

 由上面可以看出,其实spec就是一些makefile的参数,编译器,库文件,这样达到交叉编译的作用。

这样qmake就可利用这些信息生成交叉编译的makefile,

然后我们执行make即可生成针对arm的QT应用程序。



下面来看下qtopia的原理:



 其实qtopia就是一个桌面qt应用程序,但是他扩展了一些类,所以,他也有库,头文件,

然后生成的qpe就是利用这些扩展的库实现的。

我们来看下qtopia的原理;

 既然它也是应用程序,那它就有main函数,找到这个函数

  int main( int argc, char ** argv )

{

    int retVal = initApplication( argc, argv );

 

    if ( DesktopApplication::doRestart ) {

       qDebug("Trying to restart");

       execl( (QPEApplication::qpeDir()+"bin\\qpe").latin1(), "qpe", 0 );

    }

 

    return retVal;

}

很简单其实就一个 initApplication函数

int initApplication( int argc, char ** argv )

{

    cleanup();

 

#ifdef QT_QWS_CASSIOPEIA

    initCassiopeia();

#endif

 

#ifdef QPE_OWNAPM

    initAPM();

#endif

 

#ifdef QT_DEMO_SINGLE_FLOPPY

    initFloppy();

#endif

 

    initEnvironment();

 

    //Don't flicker at startup:

#ifdef QWS

    QWSServer::setDesktopBackground( QImage() );                  

#endif

    ServerApplication a( argc, argv, QApplication::GuiServer );//这个就启动一个qwserver就有了服务器了

 

    refreshTimeZoneConfig();

 

    initBacklight();

 

    initKeyboard();

 

    // Don't use first use under Windows

#ifdef Q_OS_UNIX

    if ( firstUse() ) {

       a.restart();

       return 0;

    }

#endif

 

    AlarmServer::initialize();

 

#if defined(QT_QWS_LOGIN)

    for( int i=0; i

      if( strcmp( a.argv()[i], "-login" ) == 0 ) { // No tr

       QDMDialogImpl::login( );

       return 0;

      }

#endif

 

    Server *s = new Server();//这个其实就是创建主窗口桌面窗口这个类是widget继承的

 

    (void)new SysFileMonitor(s);

#ifdef QWS

    Network::createServer(s);

#endif

 

    s->show();

 

    int rv =  a.exec();

 

    qDebug("exiting...");

    delete s;

 

    return rv;

}

 

QWSServer::setDesktopBackground( QImage() ); 这个是静态函数生成了一个image对象  qwsserver指针指向qserver对象一样其他文件以extern qwsserver来使用这些对象保证了唯一性。

 

网上有很多文章是

./configure前就指定了

 export QTDIR=$PWD/qt

 

 26 export QPEDIR=$PWD/qtopia

 

 29 export PATH=$QTDIR/bin:$QPEDIR/bin:$PATH

 

这让人产生错觉,好像./configure,make过程和上面的环境变量有关,其实没有关系,因为这个用于生成Lib,所以不需要指定和qt有关的库,所以qtdir没有用,

INCPATH       = -I../../mkspecs/linux-g++ -I. -I../../include/QtCore -I../../include/QtCore -I../../include -I../../include/QtSql -I.rcc/release-shared -I.moc/release-shared -I.uic/release-shared

LINK          = g++

且头文件文件夹都是用相对路径,所以就不需要这些变量。当然QT4以前还是要这些环境变量的否则会提示没有设置qtdir等环境变量。

    在应用程序的时候就不一样,因为这个时候是要使用这些变量,且应用程序和头文件夹的位置没有太大的关系,这样就只有用环境变量来指定,这个其实在qmake时,qmake就会使用这些变量来生成makefile

 

下面来说下使用designer编写qt程序。


首先通过designer会产生一个.ui结尾的文件,

假设是hello.ui

然后

       uic -o test.h hello.ui

      然后就会生产对应的类。

     然后我们编写代码包含这个头文件,就相当于使用了这个类。

 

jimmy@jimmy-linux:~/qt/first$ cat hello.cpp

#include

#include

#include "test.h"

int main(int argc, char *argv[]) {

     QApplication app(argc, argv);

 

 

    QDialog *window = new QDialog;

 

 

     Ui::Dialog *form = new Ui::Dialog;

     form->setupUi(window);

 

 

     window->show();

 

 

     return app.exec();

 }

jimmy@jimmy-linux:~/qt/first$

Ui::Dialog;就是用designer生成由uic处理后生成的类

然后

     qmake -project

     qmake

     make就可以了

如果上面的qmake命令执行失败那就是你的环境变量没有设置好。

然后运行

阅读(1653) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~