Hello Qt
1 #include <QApplication>
2 #include <QLabel>
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv);
6 QLabel *label = new QLabel("Hello Qt!");
7 label->show();
8 return app.exec();
9 }
第一行和第二行包含类QApplication和QLabel的定义. 对于每个Qt类,都有一个跟类名同名的头文件,里面包含了类的定义。
第5行创建一个QApplication对象,用来管理整个进程范围内的资源。QApplication类支持命令行参数作为其构造函数的参数。
第6行创建一个QLabel Widget(类似于Windows中的控件和容器的概念)来显示“Hello Qt!”. Widget可以包含其他Widget.
第7行显示Label. Widgets刚创建好都是隐藏的,在显示之前我们可以对它们进行配置(customize).
第8行把程序的控制权交给Qt. 至此,程序进入一个event loop(事件循环)。这是一种待命(stand-by)状态,等待用户事件的发生,如鼠标点击或键盘按钮。用户操作产生事件(events),也叫messages, 程序会对这些事件进行响应,在Qt平台中,这些都由Qt来做,编程人员可以不予考虑。 例如,当用户点击一个widget时,会产生一个mouse press 和一个mouse release事件。
将以后代码保存为hello.cpp.
qmake –project 产生hello.pro project文件
qmake hello.pro 产生make file.
make 进行编译
将第6行改为 QLabel *label = new QLabel(“<h2><i>Hello</i> ”
“<font color=red>Qt!</font></h2>”);
可以得到类似HTML格式显示。
第二个例子。
怎样响应用户的操作。 程序由一个按钮组成,当用户按下按钮,程序退出。代码如下:
1 #include <QApplication>
2 #include <QPushButton>
3 int main(int argc, char *argv[])
4 {
5 QApplication app(argc, argv);
6 QPushButton *button = new QPushButton("Quit");
7 QObject::connect(button, SIGNAL(clicked()),
8 &app, SLOT(quit()));
9 button->show();
10 return app.exec();
11 }
Widget会发射信号(emit signals)来指示用户的行为或一个状态已经改变。例如, QPushButton发射clicked()信号当用户按下这个按钮。一个信号可以被连接到一个槽函数(slot),这样当则个信号发射时这个槽函数就会自动执行。在我们的这个例子中,我们把按钮的clicked()信号与QApplication对象的quit()槽函数相连接。 SIGNAL和SLOT是两个宏。
Laying out Widgets.
对Widgets进行布局。在这部分,我们来学习怎么用Qt中的layout类来管理一个窗口中的多个widgets.
程序由三个widgets组成:QSpinBox, QSlider和QWidget. QWidget是程序的主窗口, QSpinBox和QSlider属于QWidget的children. QWidget是最上层的窗口,所以没有父窗口。QWidget的构造函数及其所有的子类都有一个QWidget的参数用来指定此QWidget的父widget.
源代码如下:
1 #include <QApplication>
2 #include <QHBoxLayout>
3 #include <QSlider>
4 #include <QSpinBox>
5 int main(int argc, char *argv[])
6 {
7 QApplication app(argc, argv);
8 QWidget *window = new QWidget;
9 window->setWindowTitle("Enter Your Age");
10 QSpinBox *spinBox = new QSpinBox;
11 QSlider *slider = new QSlider(Qt::Horizontal);
12 spinBox->setRange(0, 130);
13 slider->setRange(0, 130);
14 QObject::connect(spinBox, SIGNAL(valueChanged(int)),
15 slider, SLOT(setValue(int)));
16 QObject::connect(slider, SIGNAL(valueChanged(int)),
17 spinBox, SLOT(setValue(int)));
18 spinBox->setValue(35);
19 QHBoxLayout *layout = new QHBoxLayout;
20 layout->addWidget(spinBox);
21 layout->addWidget(slider);
22 window->setLayout(layout);
23 window->show();
24 return app.exec();
25 }
第8,第9行创建一个QWidget作为程序的主窗口, setWindowTitle()函数用来设置标题栏的显示。
第10和第11行各创建一个QSpinBox和QSlider。我们可以把window作为参数传给构造函数,来指示Qt QSpinBox和QSlider是window的子窗口。但是这里不必要,因为我们下面要用到Qt的layout类,layout类会自动设置它们的父子关系。
第12和13行设置QSpinBox和QSlider值的范围。
第14到17行,用来绑定spin box和slider, 确保它们显示的值相同。不管哪个widget的值改变了,都会发射一个valueChanged(int)的信号,然后另一个widget的槽函数setValue(int)就自动执行。
第18行设置spin box的值,此时QSpinBox对象发射valueChanged(int)信号,值为35.这个值被传给QSlider对象的槽函数setValue(int), 把QSlider的值也设置为35. 此时因为slider的值也改变了,slider也发射valueChanged信号,参数为35,又触发的QSpinBox对象的槽函数setValue(int). 但是这时spin box不再发射信号,因为它的值已经是35,这样避免了无限循环的可能。
第19至22行,我们用Qt的布局管理器(layout manager)来为spin box和slider widgets布局。布局管理器是用来widgets的尺寸大小和位置的一个对象。Qt有三个主要的布局管理器类:
QHBoxLayout: 用来水平的从左至右对widgets进行布局;
QVBoxLayout: 用来垂直的从上到下对widgets进行布局;
QGridLayout: 用来对widgets进行网格布局;
第22行, QWidget::setLayout()用来把一个布局管理器安装到一个窗口上,此函数会为这些widgets建立父子关系。
尽管我们没有明确的指定任何widgets的大小,QSpinBox和QSlider照样显示的很美观。这是因为QHBoxLayout自动为这些widgets设置了大小和位置。编程人员只需要把widgets放到布局管理器中,Qt会自动帮我们排布。
在第一章的最后我们列一个基本的Qt 继承树
QObject |
QCoreApplication |
QWidget |
QLayout |
QApplication |
QAbstractButton |
QAbstractSpinBox |
QAbstractSlider |
QFrame |
QBoxLayout |
QHBoxLayout |
QPushButton |
QSpinBox |
QSlider |
QLabel
|
QObject--------->QCoreApplication--------->QApplication
|
|-------> QWidget------------------------------->QAbstractButton------>QPushButton
| |
| |------------->QAbstractSpinBox------>QSpinBox
| |------------->QAbstractSlider------->QSlider
| |------------->QFrame---------------->QLabel
|---------QLayout----------->QBoxlayout-------->QHBoxLayout