1.3
窗口部件的布局
创建一个简单的例子程序,以说明如何用来布局(
layout
)来管理窗口中的窗口部件的几何形状,还要说明如何利用信号和槽来同步窗口部件。这个应用程序的运行效果,它可以用来询问用户的年龄,而用户可以通过操纵微调框(
spin Box
)或者滑块(
slider
)来完成年龄的输入。
这个应用程序由三个窗口部件组成:一个
QSpinBox
,一个
QSlider
和一个
QWidget.QWidget
是这个应用程序的主窗口。
QSpinBox
和
QSlider
会显示在
QWidget
中,它们都是
QWidget
窗口部件的子对象。换言,
QWidget
窗口部件是
QSpinBox
和
QSlider
的父对象。
QWidget
窗口部件自己则没有父对象,因为程序是把它当作顶层窗口的。
QWidget
的构造函数以及它的所有子类都会带一个参数
QWidget*
,以用来说明谁是它们的父窗口部件。
一下说明一下应用程序源代码的含义及实现的功能:
一个应用程序的源代码的基本框架是:
#include <QApplication>
//
定义一个应用程序
QApplication
类头文件,所有的
Qt
图形化应用程序都包含这个头文件,用于管理
Qt
图形化应用程序的各种资源、基本设置、控制流及事件处理。如果
Qt
是非图形化应用程序,则包含
<QCoreApplicaton>.
int main(int argc,char *argv[])
//
每个应用程序只有一个主函数,这是应用程序的入口,函数
main()
被操作系统所调用,通过将控制权交给
Qt
库,对用户有关事件的动作方案进行初始化类。主函数里有两个参数,
argc
参数是命令行参数的数量和
argv
是命令行参数的数组。这是标准的
C++
功能。
{
QApplication app(argc,argv);
//
创建一个
QApplication
对象,命名为
app,
用来管理整个应用程序所用到的资源。
QApplication
对象是一个容器,包含了应用程序顶层的窗口(或者一组窗口)。顶层窗口时独一无二的,它在应用程序中从来就没有父窗口。
QApplication
对象的任务是控制管理整个应用程序资源,因此在每个应用程序中只能有一个
QApplication
对象。此外,由于创建对象的过程中必须初始化
Qt
系统,所以在使用其它任何
Qt
工具之前,
QApplication
对象必须已经存在。
return app.exec();
//
将应用程序的控制权限传递给
Qt
。此时,程序进入事件循环状态。这是一种等待模式,程序会等待用户的动作。用户改变操纵微调框的值或者改变滑块的值,都会让产生响应的程序信号
(SIGNAL)
发送和槽
(SLOT)
处理信号的事件(
event,
也称为“消息”)。然后
QApplication
调用
exec()
方法,将
Qt
完成的事件处理及显示的工作在应用程序退出时返回
exec
()的值
}
添加一个窗口部件头文件
#include <QApplication>
#include <QWidget>
//
这里定义一个
<QWidget>
窗口部件的类头文件,这个窗口部件包含了很多如
QMenuBar,QtoolsBar,QStatusBar,QMainWindow
等等。
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QWidget *window = new QWidget;
//
定义一个
QWidget
窗口部件对象,名为
window
,并作为
QWidget
应用程序做为主窗口。
Window->setWindowTitle(“Enter Your Age”);
//
调用
setWindowTitle
()函数来设置显示在窗口标题栏上的文字。这了设置为“
Enter Your Age
”
Window->show();
//QApplication
窗口调用
show()
函数将主窗口这个部件显示出来,在创建时,
QWidget
主窗口部件是被隐藏的。
return app.exec();
}
#include <QApplication>
#include <QWidget>
#include <QSpinBox>
//
定义操纵微调框的
<QSpinBox>
类头文件
#include <QSlider>
//
定义滑块
<QSlider>
类头文件
#include <QHBoxLayout>
//
定义水平方向上排列窗口部件,从左到右(在某些文化中则是从右向左)
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QWidget *window = new QWidget;
window->setWindowTitle(“Enter Your Age”);
QSpinBox *spinBox = new QSpinBox;
//
创建一个操纵微调框对象,名为
spinBox
QSlider *slider = new QSlider(Qt::Horizontal);
//
创建一个滑块对象命名为
slider
,并且设置为水平对齐
QHBoxLayout *layout = new QHBoxLayout;
//
创建一个窗口部件布局,使用水平方向上一个水平布局管理对操纵微调框和滑块布局处理。部件管理器(
layout manager
)就是一个能够对其所负责的窗口部件的尺寸大小和位置进行设置的对象。
Qt
有三个主要的部件管理器类:
QHBoxLayout(
水平方向上排列控件,从左到右
)
、
QVBoxLayout
(在竖直方向上排列控件,从上到下)
、
QGridLayout
(按矩阵方式排列控件)
layout->addWidget(spinBox);
//
窗口布局添加一个操纵微调框窗口部件
spinBox
layout->addWidget(slider);
//
窗口布局添加一个滑块窗口部件
slider
window->setLayout(layout);
//QWidget::setLayout()
函数调用会在窗口上安装该布局管理器。从软件的底层实现上来说,
QSpinBox
和
QSlider
会自动“重定义父对象“,它们会成为这个安装了布局的窗口部件的子对象。窗口部件的位置或大小,由
QHBoxLayout
对其子对象进行合理排列。布局管理器使我们从应用程序的各种位置关系指定的繁杂纷扰中解脱出来,并且它还可以确保窗口尺寸大小发生改变时的平稳性。
window->show();
return app.exec();
}
#include <QApplication>
#include <QSpinBox>
#include <QSlider>
#include <QHBoxLayout>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QWidget *window = new QWidget;
window->setWindowTitle(“Enter Your Age”);
QSpinBox *spinBox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0,140);
//
设置操纵微调框的数值有效范围为
0
到
140
slider->setRange(0,140);
//
设置滑块的数值有效范围为
0
到
140
,跟操纵微调框数据对应上。
spinBox->setValue(40);
//
设置操纵微调框指定数值为
40
,默认是数值
0
QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
//QObject::connect
是
Qt
的最重要的特征。
Connect
()是
QObject
的静态函数,这个
connect()
调用之间建立了两个
Qt
对象(对象继承
QObject
,直接或间接)单向连接,调用了两次
QObject::connect(),
保证
spinBox
和
slider
的数据显示相同的数值。定义一个
spinBox
信号(
SIGNAL
)连接到
slider
的槽(
SLOT
)。然后翻过来连接信号(
SIGNAL
)与槽
(SLOT).
从而实现下面预想的效果:
第一步:当
spinBox
操纵窗口的值被改变时,就会发射
valueChanged(int)
信号到连接的
slider
滑块的槽,调用
setValue()
的函数,设定
valueChanged(int)
传递过来的值。
第二步:当
slider
滑块接受到
spinBox
传递过来的
signal
信号
valueChanged(int),
从而把
slider
值改变后。然后
slider
滑块又发出
valueChanged(int)
修改值的信号,传递给连接号的
spinBox
操纵微调窗口的槽,然后通过
setValue()
的函数设置操纵窗的数值,当
spinBox
的槽是
slider
信号的值时,当数值相同时不会发射任何信号了。
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);
Window->show();
return app.exec();
}
[root@localhost root]# mkdir age
//
创建一个
age
目录
[root@localhost root]# cd age/
//
切换到新建目录
age
中
[root@localhost age]# vi age.cpp
//
创建一个名为
age
标准
C++
程序源文件
#include <QApplication>
#include <QWidget>
#include <QHBoxLayout>
#include <QSpinBox>
#include <QSlider>
int main(int argc,char *argv[])
{
QApplication app(argc,argv);
QWidget *window = new QWidget;
window->setWindowTitle("Enter Your Age");
QSpinBox *spinBox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0,140);
slider->setRange(0,140);
QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
spinBox->setValue(40);
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);
window->show();
return app.exec();
}
[root@localhost age]# qmake �Cproject
//
执行
qmake �Cproject
后在
age
目录下生成一个与平台无关的项目文件
age.pro
[root@localhost age]# qmake age.pro
//
执行
qmake
后跟项目文件
age.pro
,生成一个与平台相关的
Makefile
文件
[root@localhost age]# make
//
执行
make
进行编译源代码,并生成
age.o
目标文件及
age
执行文件。
[root@localhost age]# ./age
//
执行
age
文件,看到弹出一个标题为
Enter Your Age
对话框窗口。可以测试一下
,
改变操纵微调窗口的值,看滑块是否跟着改变。如果改变说明操纵微调框的信号与滑块槽设置成功。然后反过来测试,移动滑块看操纵微调框的值是否改变,如果改变说明滑块的信号与操纵微调框槽设置成功了。
未完。。。。。。