Linux 版 (精华区)
发信人: pilot (〓〓★〓〓), 信区: Linux
标 题: Qt tutorial 1-5
发信站: 紫 丁 香 (Wed May 10 13:58:06 2000), 转信
这就是Tcpip贴的Qt tutorial,我又编辑了一下,加上了被漏掉的头文件。
Subject Qt tutorial
Posted by kensou
Posted on 5/2/2000 6:44 PM
教程:十四章
本教程介绍怎样利用Qt1.44工具包开发GUI程序.它重在介绍GUI程序设计的体系和Qt的重
要的特点,但并不全面.
第一章是从一个只有十行代码的程序开始的,后面的章节则会逐渐介绍一些概念,通过十
四
章后,第一章的十行代码会变成一个650行代码的游戏.
教程:
Hello, World!
Calling it Quits
Family Values
Let There Be Widgets
Building Blocks
Building Blocks Galore!
One Thing Leads to Another
Preparing for Battle
With Cannon You Can
Smooth as Silk
Giving It a Shot
Hanging in the Air the Way Bricks Don't
Game Over
Facing the Wall
----------------------------------------------------------------------------
--
Copyright ?1999 Troll Tech Trademarks Qt version 1.44
Subject Qt tutorial 1-----"Hello World"
Posted by kensou
Posted on 5/2/2000 6:45 PM
第一章: Hello, World!
第一个程序是非常简单的hello-world例程.它仅仅包含了可以使Qt程序能正常运行的最
小
的部分.
/****************************************************************
**
** Qt tutorial 1
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton hello( "Hello world!" );
hello.resize( 100, 30 );
a.setMainWidget( &hello );
hello.show();
return a.exec();
}
代码逐行解释
#include <qapplication.h>
这一行包含了QApplication的定义.每一个Qt程序都必须有一个QApplicate对象.
QApplication管理应用程序广泛应用的资源,例如缺省的字体和光标.
#include <qpushbutton.h>
这一行定义了QPushButton类的定义.当你要使用某个类时, 参考文档会告诉你需要包含
那
个头文件.
QPushButton是一个经典的图形按钮类,它可以被按下或释放,并且它可以控制自己的外观
,
如同其它的控件.控件是一些可以处理用户输入和绘图的图形对象.程序员可以改变它们
的
外观与feel, 和一些诸如颜色,控件的内含等显示属性.QPushButton还可以显示其他的文
本或 位图.
int main( int argc, char **argv )
{
main()函数是程序的入口.在使用Qt时,main()只是在把控制交给Qt库之前做一些初始化
的
工作.
argc是命令行参数的数目,argv是命令参数的数组.这并不是Qt 特有的,而是C++的特点,
但
是,Qt需要处理这些参数(详情见下面的介绍).
QApplication a( argc, argv );
a是本程序的QApplication对象,它被创建的目的是处理一些命令参数(例如X11下的
-display).注意,所有能被Qt识别的参数会被从argv中除去(argc 也会相应的减小为留下
的参数的数目).详情见QApplication::argv() 文档.
注意:在使用任何Qt窗口系统之前,QApplication对象必须被创建.
QPushButton hello( "Hello world!" );
这里,在QApplication对象创建之后,进入第一句窗口代码:创建一个按钮.
使此按钮显示文本"Hello world!",并且它只属于本按钮自身(因为构造函数中并没有指
明
这个按钮应属于哪个控件).
hello.resize( 100, 30 );
设置按钮的大小是100X30象素.在本例程中我们并不关心按钮的位置,只是使用了缺省的
数
值.
a.setMainWidget( &hello );
应用程序设定hello按钮为主控件,当主控件关闭后,程序退出.
主控件不是必需的,但大部分程序都有一个主控件.
hello.show();
一个控件被创建后是不可见的,你必须调用show()函数使之可见.
return a.exec();
在这里,main()将控制权交给Qt,当应用程序退出时exec()将返回.
在 exec()执行期间,Qt接收并处理用户的系统事件并且在可见控件上表现出来.
}
程序行为
现在你可以尝试编译并 运行 本程序.
当你运行它时,你会看到一个只有一个按钮的窗口,上面是那句经典的名言"Hello
World!".
练习
试着改变窗口的尺寸.按下按钮.如果你是在X11下运行本程序,不妨用 -geometry参数在
命
令行中运行它.(例如: -geometry 100X200+10+20)
下面我们进入第二章
Subject Qt tutorial 2------call it quits
Posted by kensou
Posted on 5/2/2000 6:49 PM
第二章: Calling it Quits
在第一章中,我们已经创建了一个窗口,在本章中,我们将让此程序响应用户的退出指示.
并且,我们将使用一种现有的字体来代替缺省的字体.
/****************************************************************
**
** Qt tutorial 2
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton quit( "Quit" );
quit.resize( 75, 30 );
quit.setFont( QFont( "Times", 18, QFont::Bold ) );
QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );
a.setMainWidget( &quit );
quit.show();
return a.exec();
}
代码逐行解释
#include
既然程序使用了QFont类,它就需要包含qfont.h头文件.Qt的字体的抽象描述比之X 有很
大
的不同,并且在装载和使用上进行了高度的优化.
QPushButton quit( "Quit" );
这一次,按钮显示"Quit",而且当用户点击时,程序确实会退出.但是,这是有原因的.
quit.resize( 75, 30 );
我们给按钮设置了另一个尺寸,因为这次显示的文字比"Hello World!"短多了.我们还可
以
使用QPushButton::setAutoResize()或 QFontMetrics来设置合适的尺寸.
quit.setFont( QFont( "Times", 18, QFont::Bold ) );
这里我们让按钮使用了一种新的字体:"Times"族,18点,Bold型.注意,我们当时就创建了
这
种字体.
另外,我们还可以改变整个程序的缺省字体.
QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );
connect() 可能是Qt最重要的核心特点.需注意的是connect() 是QObject 类的静态
(static) 函数,不要把它和socket库中的connect()函数混淆了.
这一行在两个Qt对象(直接或间接继承(inherit)于QObject的对象)建立的一种联接.所有
的 Qt对象都具有signals(发送消息)和slots(接收消息).所有的控件都是 Qt对象,它们
都
继承于QWidget,而QWidget则继承于QObject.
这里,按钮quit的clicked()signal被联接到应用a的quit()slots上, 所以,当按钮被点击
时,应用程序会退出.
Signals and Slots 章节有详细的介绍.
程序行为
当你运行这个程序时,你会看到一个只有一个按钮的窗口,它比第一章的那个还小.
练习
试着改变窗口的大小.按下按钮.嗷,connect()函数会带来如此的不同:)
QPushButton中还有哪些可以联接到quit的signals? Hint:QPushButton是继承于QButto
n
的,同时也继承了QButton的大部分习性.
现在,你可以进入 第三章了.
Subject Qt tutorial 3----"Family values
Posted by kensou
Posted on 5/2/2000 6:51 PM
第三章: Family Values
这个例子将演示如何创建父控件和子控件.
这个程序还是简单的,它仅仅使用了一个父控件和一个子控件.
/****************************************************************
**
** Qt tutorial 3
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
int main( int argc, char **argv )
{
QApplication a( argc, argv );
QWidget w;
w.resize( 200, 120 );
QPushButton quit( "Quit", &w );
quit.move( 62, 40 );
quit.resize( 75, 30 );
quit.setFont( QFont( "Times", 18, QFont::Bold ) );
QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );
a.setMainWidget( &w );
w.show();
return a.exec();
}
代码逐行解释
QWidget w;
这里我们简简单单地创建了一个控件.注意,我们并没有包含qwidget.h,因为我们包含了
qpushbutton.h而且,QPushButton是QWidget的一个子类(详见 Class Hierarchy).
QWidget类对象不会处理任何事件(events),它只是简单地显示自己的背景颜色 和标题
(caption)
w.resize( 200, 120 );
设置尺寸为200X120象素(pixels).
QPushButton quit( "Quit", &w );
一个孩子出生了.
一个QPushButton对象被创建了,它显示的文字是"Quit",其父控件是w.子控件总是显示在
父控件的上面.当显示时,它会受到父控件的约束.
quit.move( 62, 40 );
子控件被移动到距父控件左上角62,40象素处(包括窗口边框).坐标系是非常普通的视图
坐
标, x轴向右增加,y轴向下增加.
w.show();
当一个控件显示后,它会调用它的子控件的show()(除了你显式地调用hide()).
程序行为
注意,如果你改变控件的尺寸,按钮的位置和大小不会象前两章的程序那样改变. 那是因
为
控件是QWidget对象,它对尺寸改变不起作用.
X11的用户在使用 -geometry运行程序时也会看到同样的效果.
练习
尝试改变quit.move()和/或quit.resize()的参数,如果按钮quit溢出到控件w后会怎样?
X11用户:
同样尝试把w.resize()移到quit.move/resize的后面,或者a.setMainWidget() 的后面,
这
样,-geometry还会工作吗?
你现在可以进入第四章了.
Subject Qt tutorial 4---------"Let there be widgets"
Posted by kensou
Posted on 5/2/2000 8:00 PM
第四章: Let There Be Widgets
这个例子演示如何创建你自己的控件,怎样控制控件的最大和最小尺寸.还将引入控间名
称
(widget names).
/****************************************************************
**
** Qt tutorial 4
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
};
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
setMinimumSize( 200, 120 );
setMaximumSize( 200, 120 );
QPushButton *quit = new QPushButton( "Quit", this, "quit" );
quit->setGeometry( 62, 40, 75, 30 );
quit->setFont( QFont( "Times", 18, QFont::Bold ) );
connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MyWidget w;
w.setGeometry( 100, 100, 200, 120 );
a.setMainWidget( &w );
w.show();
return a.exec();
}
现在一行一行看下去
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
};
在这里我们创建了一个新的类(class).因为这个类继承于QWidget类,所以这个类是一个
控
件,并且它可能是一个顶层窗口(top level window)或者是一个控件.(就象第三章的按钮
).
这个类只有一个成员:构造函数(另外还有从QWidget继承来的成员).此构造函数是一个标
准的Qt控件构造函数;当你创建一个控件时,你总要包含一个简单的构造函数.
第一个参数是它的父控件.如果要创建一个顶层控件,你要指明为一个空指针作为父控件
.
如同你所见的,在缺省情况下,控件是一个顶层窗口.
第二个参数是此控件的名字.它不是在标题栏(title bar) 或在按钮中.它是一个于控件
相连的
名字,它存在的目的是使此控件在以后能易于被 识别(lookup)控件名字在以后会变得十
分有用.
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
构造函数是从这里开始执行的.象所有的控件一样,它仅仅是把parent和name 传递给了
QWidget的构造函数.
{
setMinimumSize( 200, 120 );
setMaximumSize( 200, 120 );
因为这个控件不知道如何控制尺寸调整,我们就通过设置其最大尺寸和最小尺寸相等来弥
补这一点. 在下一章,我们将演示如何让控件响应resize事件.
QPushButton *quit = new QPushButton( "Quit", this, "quit" );
quit->setGeometry( 62, 40, 75, 30 );
quit->setFont( QFont( "Times", 18, QFont::Bold ) );
这里,我们为这个控件定义并创建了一个名为"quit"的子控件.这个控件的名字与在按钮
上
显示的文字并没有什么联系,在本实例中,它们仅仅是碰巧相似而已.
注意:quit是构造函数的一个局部变量,MyWidget并不能一直保持它,但是Qt可以,而且会
在
MyWidget被销毁时自动地把它销毁.这就是MyWidget不需要析构函数的原因.另一方面,如
果你选择使用析构函数来销毁它也没有什么负面影响,子控件在将被销毁时会告知Qt.
w.setGeometry( 100, 100, 200, 120 );
setGeometry()函数的作用和前几章中的move()加上resize()的作用一样.
connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
}
因为MyWidget类不知道应用对象的名称,所以它与一个指向应用对象的Qt指针qApp.相连
.
控件是一个软件元件(software component),而且应该尽量少地依赖于其使用环境以提高
它的通用性.
要知道应用对象的名字会打破这个原则,所以Qt就提供了一个宏,qApp,来告诉象MyWidge
t
一样需要知道应用对象名字的元件.
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MyWidget w;
w.setGeometry( 100, 100, 200, 120 );
a.setMainWidget( &w );
w.show();
return a.exec();
}
这里我们用刚才声明的新控件定义了一个控件对象,设置它为主控件并执行应用.
程序行为
这个程序在行为上于前一个十分相似,不同的是在我们的实现方法上.仅仅是在习性上有
轻
微的区别. 尝试改变它的尺寸来观察一下.
练习
尝试在main()中建立另一个MyWidget对象,会有什么情况发生?
尝试增加更多的按钮或者在控件中增加除了QPushButton外的控件.
可以改变一下背景颜色(background color)
你现在可以进入第五章了.
Subject Qt tutorial 5-------"Building blocks"
Posted by kensou
Posted on 5/2/2000 8:05 PM
第五章: Building Blocks
这个例程演示了如何创建并使用信号连接结合控件,以及如何处理尺寸调节事件.
/****************************************************************
**
** Qt tutorial 5
**
****************************************************************/
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
#include <qscrollbar.h>
#include <qlcdnumber.h>
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
protected:
void resizeEvent( QResizeEvent * );
private:
QPushButton *quit;
QScrollBar *sBar;
QLCDNumber *lcd;
};
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
setMinimumSize( 200, 200 );
quit = new QPushButton( "Quit", this, "quit" );
quit->setGeometry( 10, 10, 75, 30 );
quit->setFont( QFont( "Times", 18, QFont::Bold ) );
connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
lcd = new QLCDNumber( 2, this, "lcd" );
lcd->move( 10, quit->y() + quit->height() + 10 );
sBar = new QScrollBar( 0, 99, // range
1, 10, // line/page steps
0, // inital value
QScrollBar::Horizontal, // orientation
this, "scrollbar" );
connect( sBar, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) );
}
void MyWidget::resizeEvent( QResizeEvent * )
{
sBar->setGeometry( 10, height() - 10 - 16, width() - 20, 16 );
lcd->resize( sBar->width(), sBar->y() - lcd->y() - 5 );
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MyWidget w;
w.setGeometry( 100, 100, 200, 200 );
a.setMainWidget( &w );
w.show();
return a.exec();
}
逐行解释
#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
#include <qscrollbar.h>
#include <qlcdnumber.h>
本例程新加入了两个新文件:qscrollbar.h 和 qlcdnumber.h, 因为我们使用了两个新的
类:QScrollBar 和 QLCDNumber.
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
与前一章相比没有什么不同.
protected:
void resizeEvent( QResizeEvent * );
MyWidget 现在获得了处理尺寸调节事件的能力.
resizeEvent() 是QWidget 中的一个常用的为各种控件传送事件的虚函数. 这些事件函
数
构成了Qt的中央控制流机制(mechanism)部分,另外一部分构成了 signal/slot 机制.
毫无疑问,只要用户或程序中的一部分调整了控件的尺寸,该函数就会调用.
private:
QPushButton *quit;
QScrollBar *sBar;
QLCDNumber *lcd;
};
在第三章中,MyWidget 并不能识别其子控件. 但现在它具备该功能(于是就能调整它们)
.
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
setMinimumSize( 200, 200 );
既然我们想MyWidget 处理所有尺寸大于200 x 200的像素, 我们只设定一个最小尺寸.
lcd = new QLCDNumber( 2, this, "lcd" );
lcd->move( 10, quit->y() + quit->height() + 10 );
lcd 是一个 QLCDNumber, 是一个以类似于液晶显示方式显示数字的控件. 本实例用于显
示两位数字,是this的子控件并被命名为"lcd".
它位于客户区x轴的第10像素点,并且在y轴方向距离"退出"按钮10个像素点. 建议大家阅
读一下 坐标系统(Coordinate System). 注意它的尺寸并没有在此处设定, 当MyWidget
本
身的尺寸设定以后,resizeEvent() 会自动进行处理.
当一个窗口中有多个控件时,如此般采用硬编码确定其坐标会非常的烦琐,但是Qt还没有
一
个方便的设计工具. 在这方面还有待大家的努力.
sBar = new QScrollBar( 0, 99, // 范围
1, 10, // line/page steps
0, // 初始值
QScrollBar::Horizontal, // 方向(水平)
this, "scrollbar" );
QScrollBar 是一个典型的窗口系统滚动条. 以上是一种常用的构造函数, 当然还有其它
一些参数更少的构造函数, 但是我们在调用多个函数时我们必须设定一个统一的状态.
我们不用设定滚动条的几何尺寸,尺寸调整事件会自动进行处理.
connect( sBar, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)) );
在此处我们使用了signal/slot 机制 将valueChanged() signal连接到液晶显示器的
display() slot.
无论什么时候滚动条的值发生了变化, 它就会通过产生一个valueChanged() signal而传
送一个新值. 由于该signal连接于液晶显示器的display() slot,但signal被传送后该
slot就会被自动调用. 这两个对象相互都不能识别对方. 这是组件编程的基础.
Slots 是用另外的方法实现的普通C++成员函数并遵守通用的C++ 访问规则.
void MyWidget::resizeEvent( QResizeEvent * )
{
sBar->setGeometry( 10, height() - 10 - 16, width() - 20, 16 );
lcd->resize( sBar->width(), sBar->y() - lcd->y() - 5 );
}
在本例中,我们想在窗口重绘时将子控件完好的骧入到窗口中. 我们希望液晶显示器在滚
动条的上方. 首先将滚动条放置到MyWidget的底部.
滚动条的几何位置被设定在距离左(右)以及下方的边框10个像素处, 高度设定为16个像
素
点(大多数窗口风格向导都推荐使用这种设置).
请注意setGeometry()的参数顺序是:左,上,宽度,高度.
坐标点X很简单;距离左边框10个像素点.Y点坐标则由整个控件的高度计算得来.我们扣掉
了16像素宽的边框和滚动条的高度.滚动条的宽度应该在MyWidget控件的两边至少留下1
0
个像素的宽度.正如上面提到的,我们给滚动条的高度是10个像素.
最后,液晶显示器的尺寸被调整.它的宽度十分简单.我们给它的宽度是和滚动条相等的.
高
度是从滚动条到液晶显示器的顶端的距离,当然,我们还预留了5像素的边框. s别忘了,在
构造函数中我们把液晶显示器放在quit按钮的下面.
象我们这样自动放置控件是十分烦琐的.Qt还包含了一些几何尺寸管理类(geometry
management),它会让这样的工作变得轻松.这些类就是QBoxLayout和QGridLayout. 在以
后
版本的教程中会包括关于它们的章节.Stay tuned!
程序行为
液晶显示器可以反映出你在滚动条上的动作,并且控件可以更好地处理尺寸调整事件了.
练习
尝试给液晶显示器增加更多的显示位数或者改变显示模式.你可以增加四个按钮来设置显
示其显示模式.
你还可以改变滚动条的范围.
尝试在液晶显示器溢出时让程序退出.
你现在可以进入第六章了.
--
〓〓★〓〓
比别人飞的更高,更快,更强!
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab2.hit.edu.c]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:209.660毫秒