前言
Qt 是一个著名的 C 应用程序框架
本质上来讲,Qt 是一套 C 的代码库(类库)与工具集,与开发人员的关系就像军火库对于军人的关系一样,也好比预制构件库对于建筑工程师的关系一样,可以提供各种现成的组件来高效便捷地实现 C 应用 Tip: 虽然 Qt 常被用来开发图形界面应用,但它并不仅仅局限于 GUI 应用
Qt 是一个跨平台的框架
Qt is a cross-platform application development framework for desktop, embedded and mobile. Supported Platforms include Linux, OS X, Windows, VxWorks, QNX, Android, iOS, BlackBerry, Sailfish OS and others.
一般有三种策略实现跨平台GUI :
- API 映射:界面库使用同一套 API,将其映射到不同的底层平台上面
- API 模拟:API 映射会“缺失”不同平台的特定功能,而 API 模拟可以解决这一问题,不同平台上有差异的 API,使用工具库自己的代码模拟出来
- GUI 模拟:任何平台都提供了图形绘制函数,例如画点、画线、画面等,工具库利用这些基本函数,再绘制出自己的组件,这就是 GUI 模拟
所以可想而知,同一套 Qt 代码在不同平台上生成的应用,界面风格将会迥异(随平台而定)
Qt 是 C 编程思想的集大成者,从中可以习得很多优秀的编程最佳实践
Qt is not a programming language on its own. It is a framework written in C . A preprocessor, the MOC (Meta-Object Compiler), is used to extend the C language with features like signals and slots. Before the compilation step, the MOC parses the source files written in Qt-extended C and generates standard compliant C sources from them. Thus the framework itself and applications/libraries using it can be compiled by any standard compliant C compiler like Clang, GCC, ICC, MinGW and MSVC
Qt 同时具有商业版权和开源版权,详细可以参看 版权
Qt is available under various licenses: The Qt Company sells commercial licenses, but Qt is also available as free software under several versions of the GPL and the LGPL
下面对 Qt 的相关基础进行简单地分享
Tip: 当前的最新版本为 Qt 5.8 ,此文中的基础概念参看了 《Qt 学习之路 2》
概要
平台与环境
应用的开发无法脱离具体的平台与环境,即便声称为跨平台的框架,在现实情况中,同样一套代码,在不同的平台与环境中也不一定会获得相同的效果
代码语言:javascript复制[emacs@h102 ~]$ cat /etc/issue
CentOS release 6.6 (Final)
Kernel r on an m
[emacs@h102 ~]$ uname -a
Linux h102.temp 2.6.32-504.el6.x86_64 #1 SMP Wed Oct 15 04:27:16 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
[emacs@h102 ~]$ gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c ,objc,obj-c ,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)
[emacs@h102 ~]$ qmake -v
QMake version 2.01a
Using Qt version 4.8.6 in /usr/local/Trolltech/Qt-4.8.6/lib
[emacs@h102 ~]$
Tip: 虽然 Qt 的最新版本为 Qt 5.8 ,但是这里实验依旧使用的 Qt version 4.8.6
helloworld
要求
- 使用 Qt 写一个helloworld 的GUI程序
创建项目
实际上就是创建一个专用的文件夹
代码语言:javascript复制[emacs@h102 demo]$ pwd
/home/emacs/demo
[emacs@h102 demo]$ mkdir hello
[emacs@h102 demo]$ ls
hello
[emacs@h102 demo]$
代码示例
main.cpp
#include <QApplication> //QApplication 类管理GUI程序的控制流和主设置
#include <QLabel> //QLabel 类用来进行文本或图片的显示
int main(int argc, char *argv[])
{
QApplication app(argc, argv); //创建一个QApplication对象app,使用main函数的参数进行构造
QLabel label("Hello world!"); //创建一个QLabel 对象label 使用 "Hello world!" 进行初始化
label.show(); //调用label的show方法
return app.exec(); //运行app应用
}
编译执行
代码语言:javascript复制[emacs@h102 hello]$ ls
main.cpp
[emacs@h102 hello]$ qmake -project
[emacs@h102 hello]$ ls
hello.pro main.cpp
[emacs@h102 hello]$ qmake
[emacs@h102 hello]$ ls
hello.pro main.cpp Makefile
[emacs@h102 hello]$ make
g -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.8.6/mkspecs/linux-g -I. -I/usr/local/Trolltech/Qt-4.8.6/include/QtCore -I/usr/local/Trolltech/Qt-4.8.6/include/QtGui -I/usr/local/Trolltech/Qt-4.8.6/include -I. -I. -o main.o main.cpp
g -Wl,-O1 -Wl,-rpath,/usr/local/Trolltech/Qt-4.8.6/lib -o hello main.o -L/usr/local/Trolltech/Qt-4.8.6/lib -lQtGui -L/usr/local/Trolltech/Qt-4.8.6/lib -L/usr/X11R6/lib -lQtCore -lpthread
[emacs@h102 hello]$ echo $?
0
[emacs@h102 hello]$ ls
hello hello.pro main.cpp main.o Makefile
[emacs@h102 hello]$
[emacs@h102 hello]$ ./hello
...
...
会弹出一个小窗口
编译执行过程中没有报错,从结果来看,符合预期
QApplication
代码语言:javascript复制#include <QApplication>
在Qt的应用中,我们通常都可以看到一个 QApplication 对象,那QApplication 是干嘛的?
QApplication 类管理GUI程序的控制流和主设置
QApplication 包含主事件循环, 所有来自窗口系统和其他源的事件将被处理和分配, 它也处理程序的初始化,析构和提供会话管理
对于非GUI的用QCoreApplication 代替QApplication,它不依赖QtGui库
qApp是一个全局的指针,指向QApplication的对象
QApplication的主要职责如下:
- 1.初始化程序的用户桌面设置:如palette(),font(),doubleClickInterval()(鼠标双击的时间间隔),并一直监视这些属性,以防用户改变他们(得到及时的更新)
- 2.处理事件:它接收来自底层窗口系统的事件,并把他们分发给关联的窗口,通过sendEvent(),postEvent(),你可以把你自己的事件发给部件
- 3.解析命令行参数
- 4.定义程序的观感(被封装在QStyle 对象中):通过setStyle()可以实时的改变
- 5.知道程序的窗口信息:可以通过widgetAt(),还可以得到一个窗口列表通过topLevelWidgets(),然后通过closeAllWindows()关闭所有窗口
- 6.管理鼠标操作
- 7.提供一个复杂的会话管理:它使程序在用户退出时可以“优美”的结束,或者如果干掉一个进程如果这个进程不能保留程序之前的状态(对会话管理不了解,翻译的不准确)
由于QApplication对象做了这么多初始化操作,所以它必须在所以与用户接口有关的对象创建之前被创建
Tip: 引自 《QApplication (GUI 程序中 有且仅有一个)》
QLabel
代码语言:javascript复制#include <QLabel>
它继成自 QFrame
QLabel 对象可以用来显示文本和图片
QLabel is used for displaying text or an image. No user interaction functionality is provided. The visual appearance of the label can be configured in various ways, and it can be used for specifying a focus mnemonic key for another widget
相应的属性和方法可以参阅 Qt API 文档