QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3429|回复: 8

用 QT Designer 来快速学习 QT

[复制链接]
发表于 2005-5-10 23:01:41 | 显示全部楼层 |阅读模式
写在前面∶
        这里只是告诉大家一种如何快速学习 QT 的方法.这里也只对 QT Designer
和 QT 作一个简单的介绍.让没有写过 QT 的人能对 QT 有一个初步的认识. 如果您
真的对 QT Programming 很有兴趣.这里我建议您去看看 O'REILY 出版的 Programming
with QT 和 Bible 出版的 KDE 2 /QT Programming. 这两本书将会给您带来一个好的
开始.

这篇文章适合您吗?

        这篇文章只是对 QT 的一个入门介绍.如果您有兴趣认识一下 QT 这种语言,那麽
这篇文章就很适合您了.
        如果您对 C++ 能有一些的了解,那麽您将会很轻松的看完这篇文章. 如果您什麽
程式语言也没有学过.但也想一窥 QT 的容貌.那麽也没有关系.这里都是些非常间单的东西.
也需会成为您学习写程式的一个起点.
        如果您本身已经在开发、学习 QT/KDE 或者 Xwindow 有关的程式设计.那就只能当
是打发时间看看玩了.这篇短短的文章没有写到很多的东西. 对於这些高手们,我唯一能提共
的一个经验就是多多去看 $QTDIR/include 下面的东西.



1. 什麽是 QT.

用 Linux 的人,一定都知道 QT 是什麽.而利用 QT 编译出来的 KDE 桌面系统,
更是让 Linux 有了一次能和 Windows 的 GUI 相媲美的机会.甚至有人说, KDE
的桌面在图形上,还胜过了 Windows95 了.那麽 QT 到底是什麽呢?其实 QT
就是基於 C++ 语言上的一种专门用来开发 GUI 介面的程式.这里面包括了∶
button; label; frame ... 等等很多的可以直接调用的东西.



2. 为什麽选择 QT

2.1 QT 是基於 C++ 的一种语言

相信 C/C++ 目前还是一种很多人都在学习的语言. QT 的好处就在於 QT 本身
可以被称作是一种 C++ 的延伸. QT 中有数百个 class 都是用 C++ 写出来的.
这也就是说, QT 本身就具备了 C++ 的快速、简易、Object-Oriented Programming
(OOP)等等无数的优点.



2.2 QT 具有非常好的可移植性(Portable)

QT 不只是可以在 Linux 中运作.也同样可以运行在 Microsoft Windows 中.这也就
意味者,利用 QT 编写出来的程式,在几乎不用修改的情况下,就可以同时在 Linux
中和 Microsoft Windows 中运行. QT 的应用非常之广泛,从 Linux 到 Windows 从
x86 到 Embedded 都有 QT 的影子.

3. 什麽是 QT Designer

简单的来说 QT Designer 是一个 GUI 的工具. 这个工具可以帮助我们来加快写 QT
程式的速度. 利用 QT Designer 可以用一种所见既所得的方式,来产生 QT 程式的
GUI 介面的程式码. 通过增加一些功能,就可以完成一个程式了.利用 QT Designer
可以非常快速的学会 QT, 而我们这里说利用 QT Designer 来学习 QT 而不是利用
QT Designer 来写 QT, 这里的区别就在於, QT Designer 所产生的程式码有些繁琐.
跑起来也比较的慢些.我们这里只是利用 QT Designer 来帮助我们学习.而不是直接
去跑 QT Designer 生成的程式码.

3. 基本要求

        因为这篇文章主要是告诉大家如何利用 QT Design 来达到快速学习 QT 的.
所以您最也要做到∶
       
        您需要有一台可以跑 Linux 的电脑或者 Microsoft Windows 的电脑
        足够的 RAM 和 HardDisk 用以安装、 编译 QT
        您的 Linux 中需要安装有        KDE、QT、QT Designer、g++ 等等程式.
        您如果适用 Microsoft Windows, 则您需要 VC++ 和 QT For Windows
        Linux 的使用者最好还能安装一个 Kdevelop(一个非常好的用来开发 QT 的 Develop Enverment)

4. QT Designer

简单的介绍--从 PushButton 开始
       
        假设您一切都安装好了.现在我们打开 QT Designer 吧. 打开後,选择 New -> Dialog
这时侯,您的 QT Designer 中就会出现一个 From1 来. 现在我们 click 一下上面的 tools 中
的那个 pushbutton, (标有 OK 的图标)并且用 mouse 选择到一定的大小. 在这个 pushbutton
上面用您的 mouse double click 一下. 我们就可以改变 pushbutton 的 label 了. 这里我们把
pushbutton1 这几个字,换成 Exit, 然後直接按 Enter 或者用 mouse 选择 OK 也可以. 现在我们
看到, 那个 button 中的标签已将变成 Exit 了. 我们这时侯还需要给这个 Exit Button 一个
signal(信号), 这样当您在 Exit 这个 Button 上 click 的时侯. QT 才知道如何去处理这个信
号. 我们按一下 F3(connect singnal slot)然後在那个 Exit Button 上面 Click 一下. 这时
侯我们就看到了 Edit Connection 的 Dialog 了. 在 Signal 中选择 clicked, 在 slot 中,先选
择 setFocus() 就好了. 这时侯选择 OK. 我们就算是完成了. 如果想看看这个小程式长什麽样子.
可以用 CTRL+T来看 PreView. (see figure 1)


figure 1


        首先在您的 $HOME 中建立一个 qt_program 的 Directory 出来. 这个 Directory 将会
作为我们存放文件的地方. 现在我们用 File -> Save 把这个文件存为 form1.ui 放在 $HOME/qt_program
的目录下.现在如果大家打开 form1.ui 来看一看. 会发现那是一堆有很多 <tag&g; 的不知道是什麽
的东西.所以我们需要用一个叫做 uic 的程式来把 .ui 文件转换成 QT 可以使用的 .cpp 和 .h 文件.
用下面的指令就可以生成我们需要的 .h 文件了

uic -o form1.h form1.ui
而生成 .cpp 文件则需要用以下的指令∶
uic -i form1.h -o form1.cpp form1.ui
这时侯,form1.h中就会看到一个标准的 QT 需要的 .h 文件

1. #ifndef FORM1_H
2. #define FORM1_H

3. #include <qvariant.h>  
4. #include <qdialog.h>   

5. class QVBoxLayout;
6. class QHBoxLayout;
7. class QGridLayout;
8. class QPushButton;

9. class Form1 : public QDialog
10. {
11.     Q_OBJECT

12. public:
13.     Form1( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
14.     ~Form1();

15.     QPushButton* PushButton1;

16. };

17. #endif // FORM1_H



1-2: 定义 FORM1.H 这个文件
3-4: 这里是我们需要用到的两个 .h 文件

5-7: 我们根本用不到, qt designer 自己产生的

8: QPushButton 需要用到这个 class

9-11: 我们的 form1 是 based 在 QDialog 上面的

12: 公开的 (可以在以後的程式中使用.用过 C++ 的人一定明白)
13: Form1的架构
14: 清除 Form1

15: 产生一个pushbutton (就是那个标有 exit 的 按钮

17: 结束对 FORM1.H 的定义

而 form1.cpp 文件如下:

1. #include "form1.h"

2. #include <qpushbutton.h>
3. #include <qlayout.h>  
4. #include <qvariant.h>
5. #include <qtooltip.h>
6. #include <qwhatsthis.h>

7. /*
8.  *  Constructs a Form1 which is a child of 'parent', with the
9.  *  name 'name' and widget flags set to 'f'
10.  *
11.  *  The dialog will by default be modeless, unless you set 'modal' to
12.  *  TRUE to construct a modal dialog.
13.  */
14. Form1::Form1( QWidget* parent,  const char* name, bool modal, WFlags fl )
15.     : QDialog( parent, name, modal, fl )
16. {
17.     if ( !name )
18.         setName( "Form1" );
19.     resize( 596, 480 );
20.     setCaption( tr( "Form1" ) );
                       
21.    PushButton1 = new QPushButton( this, "PushButton1" );
22.    PushButton1->setGeometry( QRect( 130, 160, 161, 71 ) );
23.    PushButton1->setText( tr( "Exit" ) );
24.    // signals and slots connections
25.    connect( PushButton1, SIGNAL( clicked() ), PushButton1, SLOT( setFocus() ) );
26. }

27. /*  
28.  *  Destroys the object and frees any allocated resources
29.  */
30. Form1::~Form1()
31. {
32.     // no need to delete child widgets, Qt does it all for us
33. }

1: 我们上面的定义文件
2: pushbutton所需要的 .h 文件
3-6: 我们根本用不到, qt designer 自己产生的
7-13: QT Designer 产生的注解
14-15: Form1 的结构
17-18: 如果Form1:Form1中没有 pass 一个名子过来.那麽就命名为 Form1
19: resize
20: 把显示出来的那个 Dialog 的名子定为 Form1, 也就是 window 中左上角的字
21: 做出一个新的button,名子为 PushButton1
22: 这里设定了 pushbutton 在这个 dialog 中的位置. Qrect(130, 160, 161, 71) 这里是说在一
个Dialog中,以左边最上面来算,位置是(0,0), 所以说,这里的130(横向)和 160 (纵向)就是说我
们从 (0,0)开始,往左边跑130,往下跑 160.这样我们就算出了pushbutton这个按钮画在那里了.後面的161,
71则是定义这个pushbutton到底要画多大,设定了长和高
23: 通过呼叫setText指令,我们可以在这个 button上面给入我们需要的文字.这里是 Exit
24: QT Designer 产生的注解
25: 上面就是处理当接收到 clicked 的信号(singal)以後,我们所作的事情(setFocus on PushButton1)
connect 这里是告诉程式连接一个信号,PushButton1, SIGNAL(clicked()),是说信号是由 PushButton1 发出,
发出的信号为 mouse clicked,PushButton1, SLOT(setFocus())表示信号发出以後,目标(Object)为 PushButton,
event 是 setFocus() 动作
26: 主程式结束
27-29: QT Designer 的注解
30-33: 清除 Form1

由於我们要常常用到 QT Designer, 也就是说,需要常常用到 uic 这苹程式. 为了省去每次都要
打一堆东西的麻烦.我们来写一各小 script 来处理 .ui 档案.
不难看出, uic 在处理/生成 .h .cpp 档案的时侯,用到了两个指令∶

uic -o form1.h form1.ui
uic -i form1.h -o form1.cpp form1.ui

所以我们的 script 就写成∶

###############################################################
#!/bin/sh                                                     #
# myuic program convert .ui to .cpp .h by calling uic         #
                                                              #
INPUT_UI=$@                                                   #
#这里读取外面传回来的文件名                                   #
                                                              #
                                                              #
if [ ! -f "$INPUT_UI" ]                                       #
then                                                          #
echo "UIC File $INPUT_UI Not Found"                           #
echo                                                          #
echo "Userage myuic input_file.ui"                            #
echo                                                          #
exit 1                                                        #
fi                                                            #
#上面的语句检查我们所输入的.ui文件是否存在                    #
#如果找不到指定的.ui文件,则显示一个简短的                     #
#使用说明                                                     #
                                                              #
INPUT_H=`echo $@ | cut -d '.' -f1`.h                          #
#这里我们利用 cut 来处理输入的 .ui 文件.                      #
#得到一个 .h 的文件名                                         #
                                                              #
INPUT_CPP=`echo $@ | cut -d '.' -f1`.cpp                      #
#同样的道理,利用 cut 产生一个 .cpp 的文件名                   #
                                                              #
uic -o $INPUT_H $INPUT_UI                                     #
#这里就是利用 .ui 产生 .h 的文件                              #
                                                              #
uic -i $INPUT_H -o $INPUT_CPP $INPUT_UI                       #
#利用 .h 和 .ui 产生 .cpp 文件.                               #
                                                              #
###############################################################

我门把这个文件存为 myuic. 并切 chmod +x 变成可执行档案.
然後 cp 到 /usr/bin 上面. 如果您在电脑中没有 root 的权限.
可以在自己的 $HOME 目录中做一个 bin 的 Directory 出来.
然後去编辑您的 .bash_profile (这里假设您用的是 bash)
如果您的 .bash_profile 中本身已经有了 PATH 这段文字,那麽
您只要在原本的 PATH 後面加上 :$HOME/bin就可以了.如果没有
那麽就在您的 .bash_profile 中写入∶

PATH=$PATH:$HOME/bin

export PATH

这样您以後就可以直接执行 myuic 这个文件了.现在试试看用 myuic 来处理
刚刚的那个 form1.ui 这个文件吧. 先把旧的 .h .cpp 都删除掉∶
rm -f *.cpp *.h
然後用 myuic 来生成新的 .cpp .h 文件∶
myuic form1.ui
这时候用 ls 就会看到 form1.cpp  form1.h  form1.ui 这三个文件了

这时侯我们只需要写一个小的main.cpp就可以编译form1.cpp了.
main.cpp非常的简单

#include "form1.h"
#include <kapp.h>

int main(int argc, char **argv)
{
        KApplication app(argc, argv, "Form1"); //KDE 是建立在QT的基础上得所以KApplication
                                              //所以kapp.h实际上包含了qapplication.h
        Form1 *form1=new Form1();             
        form1->show();
        app.setMainWidget(form1);
        return(app.exec());
}

基本上来说,很简单.然後当然就是编译啦.我建议写出来的东西都用 Kdevelop 来解决.首先 Kdevelop
介面非常的友善.又能省下写 Makefile 的麻烦.打开 Kdevelop 以後,选择 项目->新建, KDE2-Normal,
然後 选择 Next,在这一页中.注意不要在任何选项中打"x",因为我们用不到.反而会增加麻烦.最後
一直 next,然後 create , exit. 这时侯我们就已经有一个新的项目可以用了.在 menu 中选择:
项目->添加现存文件.然後把 qt_program 中的 form1.cpp form1.h 和 main.cpp 加入. 这时候只要按
一下 F9 , Kdevelop 就会自动帮您把程式 compile 出来.并且执行. 程式执行後,我们不能用 click 那个
Exit Button 退出程式.因为我们并没有给他退出的信号.现在让我们来把程式码作些改动∶

###########################################################

#form1.h
#ifndef FORM1_H
#define FORM1_H
#include <qdialog.h>
class QPushButton;
class Form1 : public QDialog
{
    Q_OBJECT
public:
    Form1(QWidget *parent=0, const char *name=0);
    QPushButton* PushButton1;
};
#endif // FORM1_H

#################################################################

#form1.cpp
#include "form1.h"
#include <qpushbutton.h>
#include <kapp.h>
Form1::Form1(QWidget* parent, const char* name): QDialog(parent, name)
{
    setCaption(tr("Form21"));
    PushButton1=new QPushButton(this,"PushButton1");
    PushButton1->setGeometry(QRect(130,160,161,71));
    PushButton1-vsetText(tr("Exit"));
    connect(PushButton1, SIGNAL(clicked()), kapp, SLOT(quit()));
}
Form1::~Form1(){}

####################################################################

main.cpp 保持不变.经过一番简化.程式码马上简单很多了.
这里我们除了把一些由 QT Design 做出的不必要的 code 挑除以外.对 form1.cpp
做了两个小改动.
1.增加了 #include <kapp.h>这个 head file.
2.我们把∶
connect(PushButton1, SIGNAL(clicked()), PushButton1, SLOT(setFocus()));
改变为
connect(PushButton1, SIGNAL(clicked()), kapp, SLOT(quit()));

同样的信号传送,但是目标对象有所改变.现在目标将作用在 kapp 上面也就是我们
的主程式(main application),而 SLOT 则是呼叫 quit(),现在 Kdevelop 中更改
程式码.然後按下 F9 .等待程式运行.这时侯我们的程式,只要在那个 Exit 的 Button
上面用 mouse click 一下. 这个程式就完全关闭了.

现在我们在这个 PushButton 中再增加一些功能.我们来看看 QT Designer 中的 ToolTip
功能. 如果您的 QT Designer 中 Property Edit 并没有自动出现.那麽请在 QT Designer
中选择 Menu 中的 Windows 然後选择 Property Edit. 只要在 PushButton1 那个 Button
上面用 mouse click 一下. 就可以对 Pushbutton1 的 Property 进行编辑. 在 Property
Edit 中的 ToolTip 後面可以进行文字输入的地方,打入下面的文字∶

Click On this Button Will Exit Main Window.

然後 sava 文件. (Form1.ui)在用我们的小 script 呼叫 uic 程式把, Form1.ui 转成
Form1.h 和 Form1.cpp
myuic form1.ui
这时侯我们来观察生成的 form1.cpp 文件,我们会发现现在这里面比一前多了些东西.
现在这里多了一行:
QToolTip::add(  PushButton1, tr( "Clicke On this Button Will Exit Main Window." ) );
这里,我们用QToolTip中的add,在 Object (PushButton1) 上面加入"Clicke On this Button
Will Exit Main window."这个字幕.现在我们在前面那个被我们简化的 form1.cpp 中,加入上面那
行程式码,因为我们需要调用到 QToolTip 所以我们也要把 qtooltip.h 给 include 进去.
#################################################################

#form1.cpp
#include "form1.h"
#include <qpushbutton.h>
#include <kapp.h>
#include <qtooltip.h> //因为我们需要用到QToolTip所以,这里要加入qtooltip.h
Form1::Form1(QWidget* parent, const char* name): QDialog(parent, name)
{
    setCaption(tr("Form21"));
    PushButton1=new QPushButton(this,"PushButton1");
    PushButton1->setGeometry(QRect(130,160,161,71));
    PushButton1->setText(tr("Exit"));
    QToolTip::add(PushButton1, tr("Click On this Button Will Exit Main Window."));
    connect(PushButton1, SIGNAL(clicked()), kapp, SLOT(quit()));
}
Form1::~Form1(){}

####################################################################
这时侯,重新编译这个 form1 的程式.您就会看到,当您把 mouse 移动到 Exit 那个按钮的时侯.
停留差不多一两秒钟. "Click On this Button Will Exit Main Window"的字样就会出现.

QPushButton 中还有一个常用的功能就是 setEnabled 了.setEnabled 通过 TRUE 和 FALSE 这两
个值.可以决定这个扭是否可以被使用者按下.
我们现在在 QT Designer 中的 Property Edit 中把 Enable 选择成 FALSE, 然後用 myuic 生成
新的程式码.
$myuic form1.ui
这时候再去观察 form1.cpp 会发现里面多了一行 PushButton1->setEnabled( FALSE ); 这一行就
把 PushButton1 设置为不可使用了. 如果需要 PushButton1 可以正常的被 Click, 那麽只要用
PushButton1->setEnabled(TRUE) 就可以了.

        提示∶ 最常用的作法通常是做出一个 SLOT 或者一个判断语句,来设定 PushButton 的状态.

QPushButton 还有一各场常被用到的功能就是 Font (字体的设定)在 QT 中,我们通过 QFont 可以
设定字体的大小,种类.
在 QT Designer 中的 Property Edit 中.有一个 Font 的选项.我们在 Font 後面的那个 ... 上面
按一下,就会出现一个可以选择 font 的 window. 这里我们以 Courier(adobe) 24 号字为例子.选择
後, Save, 然後观察重新用 uic 生成的 .cpp 程序码. 我们会发现主程式中多出了下面这些程式码∶

QFont PushButton1_font(  PushButton1->font() );
PushButton1_font.setFamily( "adobe-courier" );
PushButton1_font.setPointSize( 24 );
PushButton1->setFont( PushButton1_font );

後面还多出一个 bool Form1::event( QEvent* ev ). 这里我们先不要去理会 bool Form1::event( QEvent* ev )

只看下面这四行就好了∶

1. QFont PushButton1_font(  PushButton1->font() );
2. PushButton1_font.setFamily( "adobe-courier" );
3. PushButton1_font.setPointSize( 24 );
4. PushButton1->setFont( PushButton1_font );

第一行是用 QFont 生成 PushButton1_font. PushButton1_font 是为了给 PushButton1 做字体设定
第二行是告诉 PushButton1_font 使用那种字型. 我们这里使用的是 adobe-courier
第三行用了 setPointSize 设定了我们需要用到多大的字,这里我们用的是 24 号字.
第四行就真正的把这些值给到了 PushButton1 中.也就是说告诉 PushButton1 去改变字体的显示.
加入下面的代码以後,重新编译 form1, 就会看到那个按钮中的 Exit 这几个字明显的变大了.字体也改变
了.
        提示∶  通常在设定字体的时侯.都是用 #define 的方式在文件的开头宣告出来.
                例如 #define FONT_SIZE 24
                然後在设定时用 PushButton1_font.setPointSize(FONT_SIZE)
                这样当您要改字体的时侯,只要把 #define FONT_SIZE 後面的值改了
                整个程式中所有的字体就都改变了.而省去了在需要改变字体的时侯,
                一个个的去改变没一个 setPointSize中的值

        √ PushButton 是非常之常用的一个东西.可以说是任何程式都不可少的.通常最常见
                        的用途就是作为 "退出" 按钮,对话窗口的选择按钮等等.

QLabel 的使用∶

        现在我们再来看看 QLabel 的用法. 在 QT Designer 中, 用 Mouse 选择 Text Label,(就是那个
画了个『A』的图标.)然後用 Mouse 画出一个随便大小的 Text Label. 再用 Mouse 在这个 Label 上面 Double
Click 一下.将跳出的 Window 中的那个 TextLabel1 改成 My Label. 然後按 Save 保存文件. 用 uic 转成
.cpp 和 .h 文件.这使侯,我们发现,在 .h 文件中,多出了

class QLabel; //这里告诉程式,我们下面需要用到 QLabel
QLabel* TextLabel1; // 用 QLabel 生成 *TextLabel1


在 .cpp 中,我们则看到了多出下面这些东西.

#include <qlabel.h> //这就不用我多说了吧, include 进 qlabel.h 因为我们的 QLabel 需要
TextLabel1 = new QLabel( this, "TextLabel1" ); //定义 TextLabel1
TextLabel1->setGeometry( QRect( 130, 120, 171, 91 ) ); //设定 TextLabel 的位置
TextLabel1->setText( tr( "My Label" ) ); // 还既得我们输入的 My Label 吧.也就是给 TextLabel1 定的
                                        //显示出来的东西.就是用 setText 在这里设定的.

现在我们把这些加入到我们前面写的那个程式中.将上面的东西加入到 form1.h 和 form1.cpp 中.
不过我们这里需要做一点小小的改变.就是把 TextLabel1 的位置远一下.放造屏幕的最左上角.

我门把:
TextLabel1->setGeometry( QRect( 130, 120, 171, 91 ) );
改换成:
TextLabel1->setGeometry( QRect( 0, 0, 171, 91 ) );

重新编译我们的程式.就会看到在程式窗口的最左上角,有一排文字的出现.文字就是我们的 TextLabel 中
定义的 "My Label".
现在回到我们的程式部份.在前面的 PushButton 中,我们给我们的 PushButton 定义了字型及字体.实际
上,字型及字体的定义.在 QT 中是通用的. 我们可以用一样的方法来定义 QLabel 的字体.我们现在在程式
中加入∶
QFont TextLabel1_font(  TextLabel1->font() );
TextLabel1_font.setFamily( "adobe-courier" );
TextLabel1_font.setPointSize( 24 );
TextLabel1->setFont( TextLabel1_font );
这样我们就把这个 TextLabel改成了跟前面 PushButton 一样的字体 courier (adobe) 24 号字.

大家常常能看到 QT 中的 TextLabel 是用图片来显示的.实际上,这也很简单.我们在 QT Designer 中,
首先在我们刚刚生成的那个 TextLabel 上面用 Mouse Click 一下.把 Property Edit 的 Focus Set 到
我们得 TextLabel 上面. (如果您刚刚没有用 Mouse 在您的 QT Designer 上面乱按的话.那麽您的 Property
Edit 中的 Focus 应该本身就已经在 TextLabel 上了)这时侯,我们在 Property Edit 中找一个叫做
pixmap 的东西.在 pixmap 後面的 『...』中按一下,就出现了一个新的让您还则图片的视窗. QT Designer 中
目前可以接受的图片格式为(这篇文章用的是 QT Designer 1.1)bpm, jpeg, pbm, pgm, png 和 ppm. 所以
大家随便找一个上面格式的图片.然後选择 OK.这时侯您就会发现那个 TextLabel 变成您选择的图片了. 也许
您会发现,图片并没有完全显示出来,而是只显示了一部分.(如果您选择的图片大过您的 TextLabel 的话)这
是很常见的.在 pixmap 底下,有一个 scaledContents 的选项.只要把选项後面的值改成 True 就好了.这时侯
您看到的就是一个经过平衡收放过大小的图片了. 保存 (Save)起来.让我们来看看程式码这边是如何处理这
些图片的吧.
首先我们看到的是在 .cpp 的文件中,多出了:
#include <qimage.h>
#include <qpixmap.h>
这两个文件.这些都是处理图片时需要的.
後面也许大家就头大了.
static const char* const image0_data[] = {
xxxxx
xxxxx
xxxxx
xxxxx
......
...};
好长的一段.这些是什麽呢?看上去满复杂的.不用怀疑,这就是您放进去的那个图片.只不过这里是用
xpm 的格式来处存的.

                什麽事 XPM 呢?
                        其实 XPM 是 XPixMap的简称. XPM 是 Linux 中 X11 的一种图像处存的方法.
                在 XPM 中,图像被允许用 ASCII 文字模式来保存起来. 而 XPM 的另一个特性就是可以
                直接被 C Compiler 所接受.也就是说您可以直接把 XPM 的图片编译到您的程式中.

        把 XPM 直接编译到程式中有两个最大的好处:

        第一点是程式本身如果有很多图片,用 XPM 全部编译进程式中.就避免了在发行程式得时侯,需要附带很
        多图片的麻烦.
        第二点就是「相对」来说,被编译进程式的图片,对於一般的普通使用者来说,要改起来会比较麻烦些.
        当然,如果说您不准发行Open Source Code的程式.在没有 Source Code 的情况下.想要改您放放入的
        图片,就更家困难了.

        但是相对的,也有一些不便性∶
        程式码本身会加大很多
        图片的更改性不灵活

接下来,我们看到了下面的程式码∶

QPixmap image0( ( const char** ) image0_data ); \\image0_data 就是前面那个 XPM 的图片啦
TextLabel1->setPixmap( image0 );        \\ 这里是告诉 TextLabel1 去使用并且显示 image0 (image0_date)
TextLabel1->setScaledContents( TRUE );   \\打开自动平衡收放图片大小的功能.

QPixmap 本身其实就接受 xpm 档案. 所以我们可以不用把 XPM 的 Source 编译进程式中.而改用
QPixmap pixmap("image.xpm")的形式.当然,我们需要把图片文件转换成 XPM 的格式.这里我们用
到了 Linux 中本身为我们准备好的工具 convert. convert 本身支持非常多的图片各式的转换.
如果您有兴趣,可以用 man convert 来看看 convert 的详细内容.这里我只介绍如果把一个图片文
件转换成 xpm 的格式.我选择的是 Linux 中的代表图片.一苹可爱的小企鹅--logo.gif,相信每一个
安装了 linux 的人,应该都可以找到这个图片吧.您可以试这用 locate logo.gif 来寻找.找到以後,
把 logo.gif 复制到程式放有 form1 程式码的目录下. 然後用下面的指令来作图片的格式转换∶
convert logo.gif logo.xpm
这时侯,我们就可以看到目录中多了一个 logo.xpm 的文件了.


现在我们回到我们的 form1 程式码中.在前面加入
#include <qpixmap.h>

然後在 TextLabel的後面任何地方,加入下面三行程式码∶

QPixmap pixmap("logo.xpm"); //这里就是告诉 pixmap 我们刚刚 convert 出来的那个图片
TextLabel->setPixmap(pixmap); //让 TextLabel 调用/显示 pixmap (logo.xpm)
TextLabel->setScaledContents( TRUE ) ; //打开自动平衡收放图片大小的功能

记住喔,一定不能在 TextLabel = new QLabel( this, "TextLabel1" ); 以前加入喔!
这时侯重新编译我们的程式码,在新的程式中,您就可以看到那苹可爱的小企鹅了.您也许
会发现企鹅胖的有点变形.那是因为自动平衡是根据您的 TextLabel 的大小来收放图片的.
所以我们只要把:
TextLabel1->setGeometry( QRect( 0, 0, 171, 91 ) );
改换成∶
TextLabel->setGeometry( QRect( 0, 0, 171, 191 ) );
也就是说把高度增加 100,重新编译以後.可以看到,企鹅的大小变得正常多了.

        √ Label 也是最常用的组件.通常被用为在视窗中的文字显示.

RadioButton 的简介:

        接下来让我慢看看 RadioButton. 在 QT Designer 中,有一个圆圈圈的图案,在圆圈中
有个黑色的实心圆圈.那个就是 RadioButton 了.现在我们在我们的 form1 中,增加一个 RadioButton.
然後来观察程式码.

在 .h 文件中,多出了两行

class QRadioButton; //告诉程式我们需要用到 QRadioButton

QRadioButton* RadioButton1; //QRadioButton *RadioButton1

在 .cpp 的文件中出现了下面三行程式码,以及一个 include 文件

#include <qradiobutton.h> //QRadioButton 所需要的 include 文件
RadioButton1 = new QRadioButton( this, "RadioButton1" ); //生成一个新的 QRadioButton 在介面 this上
                                                        // this 就是只当前的主介面.也就是我们的
                                                        // Form1 : public QDialog
                                                        // 白话文的方法来说呢,就是我们这个程式的
                                                        // 主显示视窗.相信大家已定很熟习了吧.

RadioButton1->setGeometry( QRect( 260, 60, 151, 61 ) ); // 通过 setGeometry(QRect()) 来设定我们这个
                                                        // RadioButton 的大小
RadioButton1->setText( tr( "RadioButton1" ) );                // 用 setText() 来给我们的这个 RadioButton
                                                        // 命名.这里这里名为 "RadioButton1"

将上面这些程式码加入到我们的 form1.h 和 form1.cpp 中,重新编译程式,我们就看到了一个名为 RadioButton1
的 RadioButton 了.

RadioButton 除了可以用到 PushButton 中的 setEnabled( FALSE )的选项来 Disable 这个 RadioButton
以及在 QT 中通用的 setFont 以外,还提共一个非常常用的 setChecked (TRUE/FLASE) 功能.

在 QT Designer 中, 用 mouse click 一下我们刚刚生成的那个 RadioButton, 然後在 QT Designer 的
Property Edit 中.选择 checked, 在 checked 後面选择 True. 经过 uic 程式以後,重新观察 .cpp 程式
码, 您会发现,在 .cpp 文件中,多出了一行∶

RadioButton1->setChecked( TRUE ); //这行就设定了, RadioButton1 在程序一看使的时侯
                                  //就已经被设定为内定选项了.
重新编译程式码以後,就可以看出.这时侯 RadioButton1 前面已经被选中了.

选择按钮,重要就在於选择.现在我们来增加另外一组 RadioButton 就可以很简洁的看出 setChecked 的作用了.
在您的 form1.h 文件中,加入∶
QRadioButton* RadioButton2;
在 form1.cpp 文件中加入∶
RadioButton2=new QRadioButton2(this,"RadioButton2");
RadioButton2->setGeometry(QRect(260, 140, 151, 61)); //这里的位置比 RadioButton1的位置低出
                                                     //80 来.
这时侯我们重新编译後,执行程式,就会发现. RadioButton1 前面是被自动选择上了.而 RadioButton2 则
没有.

因为 RadioButton 常常被用作二选一,三选一或者多选一.所以这里向大家简单的介绍一下ButtonGroup.

在 QT Designer 中,上面那一堆小按钮中有一个是 ButtonGroup 的按钮.现在在这个上面用 mouse click
一下.然後在 QT Designer 中画出一个方的范围来. 这个范围要把刚刚我们画的那个 RadioButton 包进去
喔.一定要. (see figure 2)


figure 2


回来检查 uic 生成的 source code. 我们会发现
form1.h 中多出了
class QButtonGroup; // 用到 QButtonGroup
QButtonGroup* ButtonGroup1; // QButtonGroup *ButtonGroup1
而在 form1.cpp 中,有了

#include <qbuttongroup.h> // QButtonGroup 需要的 .h 文件

ButtonGroup1 = new QButtonGroup( this, "ButtonGroup1" ); //在主视窗中生成 ButtonGroup1
ButtonGroup1->setGeometry( QRect( 230, 40, 251, 181 ) ); // 设定ButtonGroup的位置与大小
ButtonGroup1->setTitle( tr( "ButtonGroup1" ) ); //设定显示为 "ButtonGroup1"
   
RadioButton1 = new QRadioButton( ButtonGroup1, "RadioButton1" );
//在这里,我们看到,这次不再是
//RadioButton1 = new QRadioButton( this, "RadioButton1" );
//而是把 this 换成了 ButtonGroup1 了.这也就是说,这次我们
//生成的 RadioButton1 是在 ButtonGroup1 这个介面上,而不是
//以前的主视窗了.

RadioButton1->setGeometry( QRect( 30, 30, 151, 61 ) );
// RadioButton1 的位置也有了改变. 这里的 30, 30 是以 ButtonGroup1 来
// 作为标准的.而不事主视窗.

// 下面这两行就不用多说了,大家一定知道
RadioButton1->setText( tr( "RadioButton1" ) );
RadioButton1->setChecked( TRUE );

现在我们自己把上面的程式码加入到我们的 form1.h 和 form1.cpp
中.同时把我们的 RadioButton1 从 this 改到 ButtonGroup1
位置也改变为 RadioButton1->setGeometry( QRect(30,30,151,61));
同时更该 RadioButton2 的设定. this 改成 ButtonGroup1
位置改成 RadioButton2->setGeometry( QRect(30, 100, 151, 61));
使 RadioButton2 跟 RadioButton1 的位置一样,但是低 70
重新编译程式.您就会发现这时侯的 RadioButton 变成二选一了.两个
中您只能选择一个.当您在 RadioButton2 前面用 mouse 按一下, RadioButton1
前面就会自动清除掉.



        √ RadioButton 通常是用在唯一选择中.也就是说从多个选择中,选出一个来.所以通常配合ButtonGroup
           来使用.但也可以单个独立使用.


CheckBox:

CheckBox 是一种跟 RadioButton 差不多的东西.通常的区别在於 CheckBox 被用於多重选择. CheckBox 在
QT Designer 中是一个方方的中间有个 X 的标?的东西.好像一个小箱子一样.我们现在好像 RadioButton
一样,做出两个 Checkbox, 然後在做出一个 ButtonGroup.把 checkbox 2 设定为 checked
form1.h 文件中,多出了
class QCheckBox;

QButtonGroup* ButtonGroup2;
QCheckBox* CheckBox1;
QCheckBox* CheckBox2;

而 form1.cpp 呢.也就有了
#include <qcheckbox.h>
ButtonGroup2 = new QButtonGroup( this, "ButtonGroup2" );
ButtonGroup2->setGeometry( QRect( 20, 180, 161, 141 ) );
ButtonGroup2->setTitle( tr( "ButtonGroup2" ) );
   
CheckBox1 = new QCheckBox( ButtonGroup2, "CheckBox1" );
CheckBox1->setGeometry( QRect( 20, 30, 121, 41 ) );
CheckBox1->setText( tr( "CheckBox1" ) );
   
CheckBox2 = new QCheckBox( ButtonGroup2, "CheckBox2" );
CheckBox2->setGeometry( QRect( 20, 90, 121, 41 ) );
CheckBox2->setText( tr( "CheckBox2" ) );
CheckBox2->setChecked( TRUE );

相信上面就不用我多解释,大家也一定明白了吧.实际上 CheckBox 跟 RadioButton
是一种非常类似的东西.


LineEdit--进入文字的处理

QT Designer 中有一个标有 『ab』 标?的小 Icon, 那就是 LineEdit 了.
现在我们在这里按一下,然後画出一个 LineEdit 来. 然後在这个 LineEdit
上面,用 mouse double click. 在出现的 window 中输入 "Display Some Text"

现在我们来看看程式码的变化∶

form1.h 中,定义了 LineEdit1
class QLineEdit;
QLineEdit* LineEdit1;

form1.cpp 中∶
#include <qlineedit.h>
LineEdit1 = new QLineEdit( this, "LineEdit1" ); \\生成 LineEdit1
LineEdit1->setGeometry( QRect( 130, 70, 251, 71 ) ); \\设定 LineEdit1 的位置

LineEdit1->setText( tr( "Display Some Text" ) ); \\ LineEdit1 显示的字为 "Display Some Text"

我们可以看到,在 QT Designer 的  Property Edit 中,有一个 echoMode 的选项.现在我们把他选择为
Password. 这时侯我们就看到刚刚打入的 "Display Some Text" 这几个字,已经变成了 "*******"了.
在 QT Designer 中,您可以选择 echoMode 为 Password 或者是 NoEcho. 这些通常都是用作密码输入
用的.当客户输入一组密码的时侯,屏幕上的密码输入 window 并不显示用户的密码明文. 而是采用 Password
---"*******" 或者 NoEcho ----(什麽都不显示) 来代议. form1.cpp 的程式码中会有下面的程式码出现∶
LineEdit1->setEchoMode( QLineEdit:assword );

        √ LineEdit 通常是用来显示或者读取单行的数据.

MultiLineEdit--进一步学习文字处理

MultiLineEdit 也是作为文字处理用的.但是他的功能就比 LineEdit 要强出很多了. MultiLineEdit
的 Icon 是一个上面画有 『cde』下面画有 『ab』的图案的按钮.
我们先做出一个MultiLineEdit,然後 double click, 在文字部份写入∶
This is a Multi Line Edit.
we are trying to put some text here.
:-)
然後观察程式码:
form1.h 多了
class QMultiLineEdit;

QMultiLineEdit* MutiLineEdit1;

form1.cpp中有了
#include <qmultilineedit.h>
MultiLineEdit1 = new QMultiLineEdit( this, "MultiLineEdit1" );
MultiLineEdit1->setGeometry( QRect( 70, 40, 441, 281 ) );
MultiLineEdit1->setText( tr( "This is a Multi Line Edit.\n"
                        "We are trying to put some text here.\n"
                        ":-)" ) );

这里不难看出.除了 MultiLineEdit 中的 setText 可以显示多行文字以外.
其他的东西跟 LineEdit 并没有什麽差别.

在 MultiLineEdit 中,我们还能选择些其他的选项.
常用的有, WordWrap, UndoDepth, ReadOnly, overWriteMode. 现在我们把
这些全都在 Property Edit 中选择出来.

WordWarp 选择为 NoWarp
UndoDepth 设定到 255
ReadOnly 为 FALSE
overWriteMode 为 TRUE

这时侯 form1.cpp 中就有了下面这些新的程式码∶

MultiLineEdit1->setWordWrap( QMultiLineEdit::NoWrap );
//设定我们的 MultiLineEdit1 不支援自动断行

MultiLineEdit1->setUndoDepth( 255 );
//设定在这个 MultiLineEdit1 中所输入的数据可以通过 mouse 的 undo 或者键盘的 ctrl + z
//来进行复原(undo)可以复原(undo)的次数为 255 次

MultiLineEdit1->setReadOnly( FALSE );
//设定 MultiLineEdit1 可以接受客户端的文字输入.如果这里为 TRUE ,那麽使用者
//就没有办法在这个 MultiLineEdit 输入任何的东西了.通常只有在 MutilLineEdit
//被当作纯粹的文字显示部件才会用到.

MultiLineEdit1->setProperty( "overWriteMode", QVariant( TRUE, 0 ) );
//打开 overWrite 的开关.也就是说用户输入的时侯,会把 MultiLineEdit1 中
//本身的东西 overWrite 掉. (覆盖写掉)


        √ MultiLineEdit 的应用非常的广泛.小到文字的显示,输入.大到文字的处理.好比 Kdevelop 中
的主 window, 我们大家写程式的时侯,就是在一个 MultiLineEdit 中. Kdevelop 2.x 中,那种在 error
code (make 时产生的)上面 double click, 然後上面就会自动 focus 到错误程式那行的程式.也是用
MultiLineEdit 来运作的.又例如 double click 在一段文字上面,然後 popup 新的 window 出来等等.
所以说, MultiLineEdit 真的是很重要很多用的一个物件.



LCD Number--数字的显示

在 QT Designer 中有一个画了个数字 『42』的
Icon. 在那理点一下.就可以做出一个 LCD Number 了.
同样的道理, form1.h 中有了 QLCDNumber 的 class, 也多出了QLCDNumber* LCDNumber1,
而 form1.cpp 中就多出了
<qlcdnumber.h>
LCDNumber1 = new QLCDNumber( this, "LCDNumber1" );
LCDNumber1->setGeometry( QRect( 350, 280, 111, 81 ) );
这样的一个 LCDNumber 实际上还是没有什麽作用.现在让我们回到 QT Designer 中.
在 Property Edit 里面给我们的 LCD 一些 value 再来看看.我们选择numDigits 为
2, intValue 为 10.这时侯,我们来看看. form1.cpp 中有了∶

LCDNumber1->setNumDigits( 2 ); //最多显示两个数字.也就是说可以选择从 0 到 99
LCDNumber1->setProperty( "intValue", 3 ); //最初的起始值为 3

在 QT Designer 中 LCDNumber 的  Property Edit 还有个 mode 可以用来选择.
我们可以选择 Hex, Dec, OCT, Bin 这四种模式. 我们现在选择 HEX,然後就会发
现,在 form1.cpp 中有下面的程式码∶
LCDNumber1->setMode( QLCDNumber::HEX );
setMode 是用来控制显示方式的.
所以说,QT 这里给我们提共的显示方式有∶
DEC->10进位方式
HEX->16进位方式
OCT->8 进位方式
BIN->2 进位方式

在这里,10 进位方式和16进位方式是我们常常会用到的.




5. 最後的程式

现在我们来把上面的东西结合起来,写一个小小的程式.程式本身什麽也不做.
只是给大家介绍一下程式的入门罢了∶ (see figure 3)


figure 3




main.cpp 很简单,这里我就不多讲了

//main.cpp

#include "final.h" //我们後面定义的 .h 文件
#include <kapp.h>

int main(int argc, char **argv)
{
        KApplication app(argc, argv, "Form1");
        Final *final=new Final(); // 後面的 final.h 会有定义
        final->show();
        app.setMainWidget(final);
        return(app.exec());
}

//final.h

#ifndef FINAL_H
#define FINAL_H

#include <qdialog.h>
class QButtonGroup;  //我们要用的 ButtonGroup
class QCheckBox;     //我们要用的 CheckBox
class QGroupBox;     //我们要用的 GroupBox
class QLCDNumber;    //我们要用的 LCDNumber
class QLabel;        //我们要用的 Label
class QLineEdit;     //我们要用的 LineEdit
class QMultiLineEdit;//我们要用的 MultiLineEdit
class QPushButton;   //我们要用的 PushButton
class QRadioButton;  //我们要用的 RadioButton
class QString;       //MultiLineEdit 要用到的 String

class Final:public QDialog //Final 基於 QDialog
{
Q_OBJECT public:
  Final (QWidget * parent = 0, const char *name = 0); //我们的主程式
   ~Final ();

  QButtonGroup *group_one;
  QRadioButton *radio_two;
  QRadioButton *radio_one;

// 第一个 ButtonGroup, 带两个 RadioButton (radio_two, radio_one)

  QGroupBox *group_two;
  QCheckBox *check_one;
  QCheckBox *check_two;
  QCheckBox *check_three;

// GroupBox, 饱含三个 CheckBox (check_one, check_two, check_three)

  QPushButton *ok_one;
  QPushButton *ok_two;

// 两个 Pushbutton (ok_one, ok_two) 这是给 radiobutton 和 checkbutton用的

  QLabel *click_label; //显示在 LCD 上面的文字
  QLabel *picture;     //企鹅的图形
  QLineEdit *LineEdit; //用来显示 radio button 的状态
  QMultiLineEdit *MultiLineEdit; //用来显示 check box 的状态

  QLCDNumber *LCD;  // 数字显示.用来显示 radio button 和 check box 後面的 ok 被按下去的次数.

  QPushButton *exit_button; // 退出程式
  QPushButton *clear_button; // 清除全去选项

  QButtonGroup *group_three;
  QRadioButton *dec;
  QRadioButton *oct;
  QRadioButton *bin;
  QRadioButton *hex;
  QPushButton *lcd_ok_button;

// 另外的一个 ButtonGroup,包括了 RadioButton dec, oct, bin, hex 和 push button lcd_ok_button
// 这个是用来选择 LCD 的选择方式的


  QString CHECK; // MultlLineEdit 在显示 check box 状态时,需要的一个 string

  int i; // 我们的 LCD 用来统计数字用的

  private slots:
  void check_radio (); //检查 radio button 状态的 slot
  void check_box ();  // 检查 check box 状态的 slot
  void check_lcd ();  // 检查 LCD 显示状态的 slot
  void CLEAR ();      // 清除所有选择,回覆到程式开始原状的 slot
};

#endif // 结束了


//final.cpp
#include "final.h"

#include <kapp.h>  // exit_button 需要用到 quit 来退出 kapplication
#include <qbuttongroup.h> // buttongroup 用到
#include <qcheckbox.h>    // checkbox 用到
#include &l;qgroupbox.h>    // groupbox 用到
#include <qlabel.h>       // label 用到
#include <qlcdnumber.h>   // LCD 用到
#include <qlineedit.h>    // lineedit 用到
#include <qmultilineedit.h>// multilineedit 用到
#include <qpushbutton.h>  // pushbutton 用到
#include <qradiobutton.h> // radiobutton 用到
#include <qvariant.h>     // LCD 用到
#include <qpixmap.h>     // 图像 (企鹅) 用到
#include <qstring.h>     // multilineedit 用来显示 check_box 状态的 string 用到
  
Final::Final (QWidget * parent, const char *name): //主程式开始了
QDialog (parent, name)
{
  if (!name)
    setName ("Final");
  resize (596, 480);
  setCaption (tr ("Final")); //命名为 Final

  i = 0; //计数器最开始的值是 0

  group_one = new QButtonGroup (this, "group_one");
  group_one->setGeometry (QRect (0, 0, 110, 121));
  group_one->setTitle (tr ("Group"));

  radio_one = new QRadioButton (group_one, "radio_one");
  radio_one->setGeometry (QRect (10, 20, 90, 40));
  radio_one->setText (tr ("One"));
  radio_one->setChecked (TRUE);
  
  radio_two = new QRadioButton (group_one, "radio_two");
  radio_two->setGeometry (QRect (10, 70, 90, 40));
  radio_two->setText (tr ("Two"));

// 设定第一个 buttongroup, 并且在 buttongroup 上面设定 radio button 1 和 radio button 2
// radio_one 的 default 是 checked (已经被选择的)

  group_two = new QGroupBox (this, "group_two");
  group_two->setGeometry (QRect (0, 120, 111, 201));
  group_two->setTitle (tr ("Group 2"));

  check_one = new QCheckBox (group_two, "check_one");
  check_one->setGeometry (QRect (10, 20, 90, 40));
  check_one->setText (tr ("One"));
  check_one->setChecked (TRUE);

  check_two = new QCheckBox (group_two, "check_two");
  check_two->setGeometry (QRect (10, 80, 90, 40));
  check_two->setText (tr ("Two"));

  check_three = new QCheckBox (group_two, "check_three");
  check_three->setGeometry (QRect (10, 140, 90, 40));
  check_three->setText (tr ("Three"));

// 第二个 group 我们改用 groupbox 来作范例. 并且在 group box 上面
// 生成三个 check box , check box 1, check box 2 和 check box 3
// check_one 的 default 是 checked (已经被选择的)

  ok_one = new QPushButton (this, "ok_one");
  ok_one->setGeometry (QRect (120, 30, 71, 61));
  ok_one->setText (tr ("OK"));

// 第一个 ok button, 我们用来检查 radio button 的状态

  ok_two = new QPushButton (this, "ok_two");
  ok_two->setGeometry (QRect (120, 190, 71, 61));
  ok_two->setText (tr ("OK"));

// 第二个 ok button, 用来检查 check box 的状态

  click_label = new QLabel (this, "click_label");
  click_label->setGeometry (QRect (250, 270, 190, 41));
  QFont click_label_font (click_label->font ());
  click_label_font.setPointSize (1;
  click_label->setFont (click_label_font);
  click_label->setText (tr ("Click On OK"));
  click_label->setAlignment (int (QLabel::AlignCenter));

// 在 LCD 的数字上方显示一些字. 这里我们显示的是 Click On Ok
// 也就是说, LCD 是显示的 ok button 被 mouse clicked 过的次数.
// 这里我们只显示 ok_one 和 ok_two, 简单的来说,就是显示 radio button
// 和 check box 的状态一共被检查过几次

  picture = new QLabel (this, "picture");
  picture->setGeometry (QRect (480, 10, 110, 140));
  picture->setText (tr ("Picture"));

  QPixmap pixmap ("logo.xpm");
  picture->setPixmap (pixmap);
  picture->setScaledContents (TRUE);

// 我用 convert 这苹程式,把那个企鹅的 logo (logo.gif) 转换成了 logo.xpm
// 这里我们把这个 loggo 读进来. 并且让 picture 这个 QLabel 作为我们的显示
// 对象. 这样我们的程式里面就有了一苹象徵 Linix 的小企鹅了.

  LineEdit = new QLineEdit (this, "LineEdit");
  LineEdit->setGeometry (QRect (210, 30, 251, 51));
  LineEdit->setReadOnly (TRUE);

// 我们这里用 lineedit 用来显示 radio button
// 所以我们把 LineEdit 设定为 setReadOnly (TRUE) 只读

  MultiLineEdit = new QMultiLineEdit (this, "MultiLineEdit");
  MultiLineEdit->setGeometry (QRect (210, 150, 250, 90));
  MultiLineEdit->setReadOnly (TRUE);

// 我们用 MultiLineEdit 来显示 check box 的状态
// 同样的道理,这里我们也不需要输入,所以设定 MultiLineEdit 为只读

  LCD = new QLCDNumber (this, "LCD");
  LCD->setGeometry (QRect (220, 320, 231, 91));
  LCD->setNumDigits (10);
  LCD->setProperty ("intValue", 0);

// 因为考虑到我们会使用 bin (二进位)的方法来显示
// 所以把显示的最大位设置为 10 位 LCD->setNumDigits (10)
// 并且设定初始值为 0
// LCDNumber 的内定显示是 DEC 的. (十进位)

  group_three = new QButtonGroup (this, "group_three");
  group_three->setGeometry (QRect (470, 170, 111, 221));
  group_three->setTitle (tr ("LCD"));

  dec = new QRadioButton (group_three, "dec");
  dec->setGeometry (QRect (10, 60, 81, 21));
  dec->setText (tr ("Dec"));
  dec->setChecked (TRUE);

  oct = new QRadioButton (group_three, "oct");
  oct->setGeometry (QRect (10, 90, 81, 31));
  oct->setText (tr ("OTC"));

  bin = new QRadioButton (group_three, "bin");
  bin->setGeometry (QRect (10, 120, 91, 31));
  bin->setText (tr ("Bin"));

  hex = new QRadioButton (group_three, "hex");
  hex->setGeometry (QRect (10, 30, 81, 21));
  hex->setText (tr ("Hex"));

  lcd_ok_button = new QPushButton (group_three, "lcd_ok_button");
  lcd_ok_button->setGeometry (QRect (10, 160, 91, 51));
  lcd_ok_button->setText (tr ("OK"));

// 在 LCD 旁边再建立一个 group ( Button Group ) 里面包含了 radio button 和 bush button
// radio button 有 dec, oct, bin, hex 这四项. 用来选择 LCD 的显示模式 (8进位,10进位,16进位,2进位)
// lcd_ok_button 是一个 push button. 最为选择 LCD 显示模式的 『确定』键


  clear_button = new QPushButton (this, "cler_button");
  clear_button->setGeometry (QRect (10, 420, 131, 41));
  clear_button->setText (tr ("Clear All"));

// 这个显示为 clear all 的 push button, 用来把
// 所有的值都设定到原始状态

  exit_button = new QPushButton (this, "exit_button");
  exit_button->setGeometry (QRect (430, 420, 131, 41));
  exit_button->setText (tr ("Exit"));

// 退出程式用的 push button

  connect (ok_one, SIGNAL (clicked ()), this, SLOT (check_radio ()));
// 连接一个信号,如果 ok_one 被 click 了,就去执行 check_radio()

  connect (ok_two, SIGNAL (clicked ()), this, SLOT (check_box ()));
// 连接一个信号,如果 ok_two 被 click 了, 就去执行 check_box()

  connect (lcd_ok_button, SIGNAL (clicked ()), this, SLOT (check_lcd ()));
// 连接一个信号,如果 lcd_ok_button 被 click 了,就去执行 check_lcd()

  connect (clear_button, SIGNAL (clicked ()), this, SLOT (CLEAR ()));
// 连接一个信号,如果 clear_button 被 click 了,就去执行 CLEAR ()

  connect (exit_button, SIGNAL (clicked ()), kapp, SLOT (quit ()));
// 连接一个信号,如果 exit_button 被 click 了, 就把我们的整个程式关闭掉
}

Final::~Final () //
{

}

void Final::check_radio ()
{
  i++;
  if (radio_one->isChecked ())
    LineEdit->setText (tr ("Radio Button 1 is Checked"));
  if (radio_two->isChecked ())
    LineEdit->setText (tr ("Radio Button 2 is Checked"));
  LCD->display (i);
}
// 在 check_radio () 中.我们用 isCheck() 来检查 radio button 的状态
// 如果 radio button 是被选择的,那麽 isCheck() 将会返回 TRUE
// 如果 radio button 没有被选择,则返回 FALSE 的值
// 如果说 radio_one 有被选择,我们就用 setText() 在 LineEdit 中显示 Radio Button 1 is Clicked
// 这几个字
// 如果 radio_two 有被选择,我们就用 setText() 在 LineEdit 中显示 Radio Button 2 is Clicked
//
// 在一开始,有个 i++, 这是我们用来统计 ok_one 和 ok_two 被 clicked 的次数用的
// 如果进入 check_radio() 就证明, ok_one 已经被 click 过一次.所以我们把 i+1,
// 然後用 display() 在 LCD 上面显示 i 的值

void Final::check_box ()
{
  i++;
  if (check_one->isChecked ())
    CHECK = CHECK + "Check Box 1 is Checked\n";
  if (check_two->isChecked ())
    CHECK = CHECK + "Check Box 2 is Checked\n";
  if (check_three->isChecked ())
    CHECK = CHECK + "Check Box 3 is Checked\n";
  MultiLineEdit->setText (CHECK);
  CHECK = "";
  LCD->display (i);
}
// check box 这里看上去稍稍比 radio button 复杂一些. 因为 radio button 我们只能选择
// 一个. 要麽就是 radio_one, 要麽就是 radio_two. 所以用个 LineEdit 就可以搞定.
// 但是 check box 是可以多项选择的.也就是说既可以是 check box1 单一的被选择. 也可以
// 是 check box 1 + check box 2, 还可以 check box 1 + check box 2 + check box 3.又或者
// check box 2 + check box 3 等等.所以这里我们需要用到 MultiLineEdit 来显示多行的信息.
// 而信息就放在我们的 QString 中 (CHECK)
// 我们用 isChecked() 来检查 check_one, 如果 check_one 被选择
// CHECK (我们的QString)就等於 CHECK+"Check Box 1 is Checked\n", 那麽 CHECK (QString)
// 本身是空的.所以这里 CHECK 就等於 Check Box 1 is Checked 这几个字.後面的 \n 是 10, 也
// 就是 换行符号的意思
// 同样的,如果 check_two 有被选择,那麽 CHECK 就等於 CHECK+"Check Box 2 is Checked\n",
// 这时侯就是两种情况. 1. check_one 没有被选择,所以这时侯,我们的 String Check 就是空
// 的+"Check Box 2 is Checked\n" 这几个字. 而如果 check_one 是有被选窄的.那麽 String
// CHECK 本身已经包含了 "Check Box 1 is Checked\n"的字.这时侯在加上 "Check Box 2 is
// Checked\n" 这几个字. 那麽 String CHECK 就有两行得内容了.
// check_three 的道理跟 check_two 是一样的. 只不过这时侯由两种可能变成了四种而已
// 1. check_one clicked + check_two clicked
// 2. check_one clicked
// 3. check_two clicked
// 4. check_one 和 check_two 都没有被 click
// 然後我们用 setText 把 String CHECK 显示到我们的 MultiLineEdit 上面去.
// 并且把 CHECK 中的 String 清除. (下次检查状态的时侯还要用到)
// 因为 ok_two 被 click 过了,所以我们的 i 又加了 1, 并且在 LCD 中显示出来

void Final::check_lcd ()
{
  if (dec->isChecked ())
    {
      LCD->setMode (QLCDNumber::DEC);
    }
  if (hex->isChecked ())
    {
      LCD->setMode (QLCDNumber::HEX);
    }
  if (oct->isChecked ())
    {
      LCD->setMode (QLCDNumber::OCT);
    }
  if (bin->isChecked ())
    {
      LCD->setMode (QLCDNumber::BIN);
    }
}

// 这是最间单的一个了
// 检查∶
// dec 有被选择, 将 LCD 显示模式改变为 DEC
// hex 有被选择, 将 LCD 显示模式改变为 HEX
// oct 有被选择, 将 LCD 显示模式改变为 OCT
// bin 有被选择, 将 LCD 显示模式改变为 BIN



void Final::CLEAR ()
{
  LineEdit->clear ();
  MultiLineEdit->clear ();
  radio_one->setChecked (TRUE);
  dec->setChecked (TRUE);
  check_one->setChecked (TRUE);
  check_two->setChecked (FALSE);
  check_three->setChecked (FALSE);
  LCD->setMode (QLCDNumber::DEC);
  i = 0;
  LCD->setProperty ("intValue", 0);
}

// 这里我们把所有选项变回程式开始的原始状态.
// 并且把显示的状态情况清空, LCD 设定回 0
// LineEdit->clear () 通过呼叫 clear() 把 LineEdit 清空
// MultiLineEdit->clear () 一样的道理. 用 clear() 清空
// 用 setChecked() 来把 radio_one 设定为『已选择』
// 用 setChecked() 把 dec 设定为 『已选择』
// 对於 radio button 来说.比较方便.因为我们从众多选择中
// 只能选择一个. 但是对於 check box 就不一样了. check box
// 可以被任意的多项选择.所以我们只好把每一个 check box 的
// 状态都设定一遍
// check_one->setChecked ( TRUE ) check_one 设定为『已选择』
// check_two->setChecked ( FALSE ) check_two 设定为没有被选择.
// check_three->setChecked ( FALSE ) check_three 设定为没有被选择
// LCD->setMode (QLCDNumber::DEC) 把 LCD 的显示模式设定为 10 进位
// i=0; 把 LCD 的计数器设定为 0
// LCD->setProperty ("intVale", 0); 将 LCD 初始化,初始值为 0


大家编译程式後,可以自己跑跑看.也可以将我们前面有说到的一些功能
自行增加进去. 例如 tooltip; PushButton 中的 setEnabled; QFont
等等.  


6. 後记

其实 QT 所提共得功能远远不只我上面所介绍的那麽一点点.这篇文章只是
让没有用过 QT 的人,能对 QT 有一个简单的概念.迈出走向 QT 的第一步.
QT Designer 只是一个辅助工具.能帮助大家快速的建立一个 QT 的概念.但是
真正要学 QT 的话. 还是建议各位读者能好好的打好基础.(C++)自己慢慢的
一点点学起. 在您的电脑中, 安装 QT 的时侯,有安装一个 Online Reference
的文件. 通常在您的 $QTDIR/doc/html 中.您可以用自己喜爱的 web browser
来查看那些文件.真正有用的东西,都全都在那里面!


PS. 唉,说好听些是说我只写写简单的入门介绍.让大家有个低门槛可以过.所以
只写点皮毛.说实话是,昨天公司突然有事情要我忙.现在又给忙上班了.真的是
没有时间来写.只好快快的结束.对不起大家了.所以从 LineEdit 开始,就是在
赶时间了. 最後那个 final.cpp 还好是我前两天先写好的.不然可能也就省掉
了.有问题的话,来问我就好啦. [email protected]
发表于 2005-5-11 12:40:15 | 显示全部楼层
写的真不错,呵呵,很适合我这个刚刚开始学习QT的人呢,谢谢你啦!顶~~~ :-)
回复

使用道具 举报

发表于 2005-5-12 17:09:24 | 显示全部楼层
不错!
我要搞个pda,也正准备用qt做界面!
我觉的应该给qt,minigui,等专门开个gui专区!
回复

使用道具 举报

发表于 2005-5-15 02:03:19 | 显示全部楼层
非常感谢!!
在很久很久之前我着想得这么一编出色的教程.
现在终于得到了,,谢谢谢!!~~
回复

使用道具 举报

发表于 2005-5-16 20:16:20 | 显示全部楼层
写的很不错顶一下
回复

使用道具 举报

发表于 2005-5-29 09:18:34 | 显示全部楼层
好文章,顶……
回复

使用道具 举报

发表于 2005-11-23 15:56:35 | 显示全部楼层
wssas
回复

使用道具 举报

发表于 2005-11-23 15:57:44 | 显示全部楼层
写得好我想问一下谁做QT的移值呢可以教一下我吗.
回复

使用道具 举报

发表于 2006-3-9 11:38:38 | 显示全部楼层
嗯,谢谢了,真的写得不错呀
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-2 20:17 , Processed in 0.137366 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表