Part 01 走近Qt
——2012.01.15
0. 本次学习Qt时主要方法:分析代码,从分析中学习语法,从分析中掌握Qt的程序设计思路。
1. 编写学习笔记主要形式:展示程序功能,从功能分析程序,总结程序设计思路,摘录(经修改)代码。
2. 主要参考学习书籍《零基础学Qt编程》(吴迪)和《C++ GUI Qt 4编程(第二版)》电子工业出版社。
3. 本Part内容:走近Qt, 从这一部分的学习中,开始熟悉Qt的设计,语法,基本概念。
001 Program– Hello Qt Version 1
01.展示程序功能
如图,这是一个简单的Widget,Widget上带不可让用户编辑的文字“Hello Qt !”。
02.从功能分析程序
可以猜测,这上面,只有一个Label,那么,只需要一个Widget就可以完成程序的设计了。另外,在Hello这个字体上,也曾作修改,在这个小细节上面,可以使用HTML样式显示字符。
03. 总结程序设计思路
对于这个简单的Qt程序设计,只需要6步完成:
注:从所见到的功能开始分析需要如何去写:
第1步:知道要设计的是QLabel对象,需要创建带“Hello Qt!”文字的QLabel对象。
第2步:因为创建的QLabel对象在屏幕上默认是隐藏的,所以需要使QLabel对象显示。
注:完成所见到的功能需要解决的问题后,分析整个程序还需要哪些功能对象参数:
第3步:需要知道添加每个Qt程序有且只有一个的必需的步骤,定义QApplication对象。
第4步:要让窗口停留,还需要调用QApplication的函数exec(),等待用户响应事件。
注:知道需要的参数对象后,需知道包含的头文件及需用到函数个数:
第5步:要定义QApplication和QLabel对象,分别需要 #include <QApplication> 和 <QLabel>
第6步:由于程序功能简单,只需要一个main函数就可以完成整个程序的编写了。
04.程序代码
// main.cpp #include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 定义了一个QApplication的对象,用于管理整个应用程序所用到的资源。 // QApplication构造函数需要argc和argv两个参数。 QLabel * label = new QLabel(QObject::tr("<h2><i>Hello</i> Qt!")); // 创建一个QLabel窗口部件(Widget),用于显示"Hello Qt"。 // 窗口部件就是用户界面中的一个可视化元素 // 另外,通过简单的HTML样式的格式,可以修改文字中的字体属性 label -> show(); // 在创建窗口部件时,标签都是隐藏的,通过调用show()显示,可以避免闪烁现象 return app.exec(); // 将应用程序的控制权传递给Qt // 此时,程序进入事件的循环状态,等待模式,直到用户动作,产生响应程序的消息 }
05. 现阶段的学习未解决的问题
第01个:为什么申请QApplication对象就一定要带argc和argv的两个参数呢?
第02个:为什么创建的那个有且只有一个的QApplication对象可管理整个应用程序所用到的资源?
002 Program– Hello Qt Version 2
01. 展示程序功能
如图,这也是一个简单的Widget,但与第一个版本的Hello Qt! 稍有不同,这个版本的Hello Qt, 多了一个点击退出的功能,当使用鼠标占击Hello Qt!的Widget时,该程序将会退出。
02.从功能分析程序
虽然这上面多了这么一个功能,但是,跟第一程序一样,这上面,也只有一个Widget,只是,这个Widget上面不是Label,而是PushButton,同样,只需要一个PushButton,一个Widget就可以完成程序的设计了。
03.总结程序设计思路
基本上与第一个Program一样,只需要7步完成,修改了一个对象,增加了一个功能:
注:从所见到的功能开始分析需要如何去写:
第1步:知道要设计的是QPushButton对象,需要创建带“Hello Qt!”文字的QPushButton对象。
第2步:因为创建的QPushButton对象在屏幕上默认是隐藏的,所以需要使QPushButton对象显示。
注:完成所见到的功能需要解决的问题后,分析整个程序还需要哪些功能对象参数:
第3步:因为该QPushButton对象需要响应用户鼠标操作,所以需要添加一个Qt信号/槽机制。
第4步:需要知道添加每个Qt程序有且只有一个的必需的步骤,定义QApplication对象。
第5步:要让窗口停留,还需要调用QApplication的函数exec(),等待用户响应事件。
注:知道需要的参数对象后,需知道包含的头文件及需用到函数个数:
第6步:要定义QApplication和QPushButton对象,需要 #include <QApplication> 和 <QPushButton>
第7步:由于程序功能简单,只需要一个main函数就可以完成整个程序的编写了。
04. 程序代码
// main.cpp #include <QApplication> // Qt GUI应用程序需要包含的文件 #include <QPushButton> // QPushButton窗口部件提供了命令按钮 int main(int argc, char * argv[]) { QApplication app(argc, argv); // 创建一个QApplication对象,用于管理整个应用程序所用到的资源。 // 每个Qt都有且只有一个QApplication对象 // 这个QApplication构造函数需要argc和argv作为参数,以支持程序的命令行参数 QPushButton pushButton(QObject::tr("Hello Qt!")); // 创建了一个QPushButton对象,它是一个窗口部件(widget) pushButton.show(); // 将按钮对象显示出来,先设属性,再显示,这样可以防止闪烁 QObject::connect(&pushButton,SIGNAL(clicked()), &app, SLOT(quit())); // 使用Qt信号/槽机制。 return app.exec(); // 程序进入事件循环,等待用户的动作并适时作出反应(执行槽函数). }
05. 现阶段的学习未解决的问题
第01个:为什么QObject::connect需要放在show()的后面,放在它前面会有什么优缺点吗?
003 Program–Simple Widget Layout (简单的窗口布局)
01. 展示程序功能
And Then: 可进行鼠标拖动或者输入数值以改变数值大小:
02. 从功能分析程序
这个程序的名称是:Simple Widget Layout,当然,首先能看到的是窗口布局,这个窗口有两个窗口部件,一个是spin box 微调框窗口部件,一个是slider滑块部件,采用了在水平方向上排列窗口部件的布局。
另外,这个程序还具有数值改变且不同窗口间的数值能相互对应的功能,与第二个程序的不同点是它没有PushButton窗口,但是新添了spin box,和slider。
03. 总结程序设计思路
程序尚算简单,只有三个窗口对象,一个布局对象,思路分为九步。
注:从所见到的窗口开始分析需要如何去写:
第01步:知道要添加的是QSpinBox对象和QSlider对象,两个子窗口。
第02步:知道还需要一个QWidget主窗口以管理这两个对象。
第03步:需要一个QLayout对象给这些窗口布局。
注:完成所见到的功能需要解决的问题后,分析整个程序还需要哪些功能对象参数:
第04步:需要知道添加每个Qt程序有且只有一个的必需的步骤,定义QApplication对象。
第05步:要让窗口停留,还需要调用QApplication的函数exec(),等待用户响应事件。
第06步:需要给QSpinBox对象和QSlider对象设定初值,设定数值范围等基本参数。
第07步:需要建立两个信号/槽机制,以实现两窗口能相互响应数值变化的功能。
注:知道需要的参数对象后,需知道包含的头文件及需用到函数个数:
第08步:须包含<QApplication>, <QHBoxLayout>, <QSlider>, <QSpinBox>, <QHBoxLayout>
第09步:由于程序功能简单,只需要一个main函数就可以完成整个程序的编写了。
04. 程序代码
// main.cpp #include <QApplication> // Qt GUI 应用程序需要包含的文件 #include <QHBoxLayout> // 窗口布局 #include <QSlider> // 滑块 #include <QSpinBox> // 微调框 int main(int argc, char *argv[]) { QApplication app(argc, argv); // 定义一个QWidget变量作为主窗口,并设定窗口标题 QWidget * window = new QWidget; window -> setWindowTitle(QObject::tr("Enter Your Age")); // 创建 QSpinBox 和 QSlider 这两个子窗口,并设定窗口中的数值范围 QSpinBox * spinBox = new QSpinBox; QSlider * slider = new QSlider(Qt::Horizontal); spinBox -> setRange(0, 130); slider -> setRange(0, 130); // 设定 SpinBox 的初值,并且使 SpinBox 与 Slider 的数值同步,可以通过 connect 函数来实现。 QObject::connect(spinBox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int))); QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int))); spinBox -> setValue(35); // 下面的语句,用到了一个布局管理器对微调框和滑块进行布局处理。 // 布局管理器(layout manager)就是一个能够对其所负责窗口部件的尺寸大小和位置进行设置的对象。 // Qt 的 layout manager 主要有3: // QHBoxLayout 在水平方向上排列窗口部件,从左到右。 // QVBoxLayout 在竖直方向上排列窗口部件,从上到下。 // QGridLayout 把窗口部件排列在一个网格中。 // 设置水平方向上排列的窗口布局(从左往右) QHBoxLayout * layout = new QHBoxLayout; layout -> addWidget(spinBox); layout -> addWidget(slider); // 这里与最上面所创建的主窗口对应,定义主窗口的布局 window -> setLayout(layout); // 显示主窗口 window -> show(); return app.exec(); }
05. 现阶段的学习未解决的问题
第01个:在给Slider和Spin Box设定范围的时候,数值大小也会受到int的大小限制吗?
第02个:QGridLayout所说的把窗口部件排列在一个网格中,再具体一点的话,是什么意思呢?这个还需要查资料去理解。