初识QT,你了解吗?

一、什么是QT

Qt 是一个跨平台的C++应用程序开发框架。它提供给开发者建立图形用户界面所需的功能,广泛用于开发GUI程序,也可用于开发非GUI程序。Qt是完全面向对象的,很容易扩展,并且允许真正地组件编程。Qt使用标准的C++和特殊的代码生成扩展(称为元对象编译器Meta Object Compiler, moc)以及一些宏。

基本上,Qt 同 X11上的GTK、Motif、Openwin和Windows上的MFC,OWL,VCL,ATL 是同类型的东西,但是 Qt 支持更多的平台(包括Microsoft Windows、GNU/Linux、Mac OS X、AndroidiOS、WinCE、UNIX家族等),面向对象且模块化程度更高(Qt 提供了一种称为 signals/slots 的安全类型来替代 callback,这使得各个元件之间的协同工作变得十分简单),丰富的API(Qt 包括多达 250个以上的 C++ 类,还提供基于模板的 collections, serialization, file, I/O device, directory management, date/time 类。甚至还包括正则表达式的处理功能),支持 2D/3D 图形渲染,支持 OpenGL、大量的开发文档、XML支持等。使用Qt开发的软件,相同的代码可以在任何支持的平台上编译运行,而不需要修改源代码。它会自动根据平台的不同,表现平台特有的图形界面风格。

经过多年发展,Qt不但拥有了完备的C++图形库,而且近年来的版本逐渐集成了数据库、OpenGL库、多媒体库、网路、脚本库、XML库、WebKit库等等,其核心库也加入了进程间通信、多线程等模块,极大地丰富了Qt开发大规模复杂跨平台应用程序的能力,真正意义上实现了其研发宗旨“Code Less; Create More; Deploy Anywhere.”

二、QT在windows下的环境搭建

在windows环境下,可以使用vs+qt的开发环境进行项目开发,环境搭建时有些细节要注意:

1)下载

下载时要注意下载和vs版本相匹配的qt版本,以及Add-in工具。找到对应的版本进行下载,里面包含多种不同的版本,MSVC2010、MSVC2012分别是指支持VS2010与VS2012的Qt版本,而opengl与非opengl的区别是是否支持opengl,android、ios分别是指支持android、ios平台的Qt版本。这里我选择的版本(已标注),如下:

l qt-windows-opensource-5.2.0-msvc2010_opengl-x86-offline.exe(opengl版本)

l Visual Studio Add-in 1.2.2 for Qt5

如图:

初识QT,你了解吗?初识QT,你了解吗?

2)安装

qt-windows-opensource与Visual Studio Add-in的安装顺序没什么要求,安装路径不要包含中文、空格、特殊字符(~<>|?*[email protected]#$%^&:,;)。

安装完成Visual Studio Add-in之后,VS就会出现相应的Qt选项!

初识QT,你了解吗?


3)配置开发环境


l 选择:Qt5->Qt Options->Add,配置VS的开发环境。

初识QT,你了解吗?

这里根据自己的Qt安装路径进行选择,Path为:D:\Software\Qt\Qt5.2.0\5.2.0\msvc2010_opengl。

到这里,开发环境就配置完成了,可以导入或者新建项目了。

导入Qt的pro项目

l 选择:Qt5->Open Qt Project File(.pro)...

新建Qt项目

l 选择:文件->新建->项目->Qt5 Projects->Qt Application,输入工程名,下一步...进行新建。

新建完成之后,就可以运行了!

三、QT的一些特点以及简单使用

1)图形用户界面

Qt的图形用户界面的基础是QWidget。Qt中所有类型的GUI组件如按钮、标签、工具栏等都派生自QWidget,而QWidget本身则为QObject的子类。Widget负责接收鼠标,键盘和来自窗口系统的其他事件,并描绘了自身显示在屏幕上。每一个GUI组件都是一个widget,widget还可以作为容器,在其内包含其他Widget。

下面以登陆窗口为例:


左侧的列表是QT的控件列表,列表中的所有控件都可以放在QWidget上。

QWidget显示能力包含了透明化等功能。

设置透明化,有几种方式,我们这里用到的是设置样式表的方式,下面的例子是设置QLineEdit控件透明无边框,如图:

初识QT,你了解吗?

Qt提供一种托管机制,当Widget于创建时指定父对象,就可把自己的生命周期交给上层对象管理,当上层对象被释放时,自己也被释放。确保对象不再使用时都会被删除。

这个登陆窗口中的所有控件的父widget都是这个窗口,所以在窗口被销毁时,所有控件也同时被销毁,不需要自己去控制。所以析构函数的实现函数中可以不进行处理,代码如下:

LoginDialog::~LoginDialog()

{

}


2)信号与槽机制(Signals and Slots)

Qt利用信号与槽(signals/slots)机制取代传统的callback来进行对象之间的沟通。当操作事件发生的时候,对象会发射一个信号(signal);而槽(slot)则是一个函数接受特定信号并且运行槽本身设置的动作。信号与槽之间,则通过QObject的静态方法connect来链接。

例如:

connect(ui.pushButton_close, SIGNAL(clicked()), this, SLOT(closeSlot()));

当关闭按钮被点击时,会触发QPushButton的clicked()信号,信号被发射之后,会连接到接收者定义的槽函数中,这里是closeSlot();

信号在任何运行点上皆可发射,甚至可以在槽里再发射另一个信号,信号与槽的链接不限定为一对一的链接,一个信号可以链接到多个槽或多个信号链接到同一个槽,甚至信号也可连接到信号。

信号与槽机制也确保了低耦合性,发送信号的类并不知道是哪个槽会接受,也就是说一个信号可以调用所有可用的槽。此机制会确保当在”连接”信号和槽时,槽会接受信号的参数并且正确运行。

这里,我想谈的是Qt算是发明了signal/slot,这个思想也被其他一些框架语言借鉴了。

谈signal/slot之前先来谈谈C++的缺欠,这里只谈一点,C++的设计目标是面向对象语言,它不仅提供了对象的定义和构建的方式,也定义了对象间的关系,比如 继承 派生 聚合,但是它没有提供对象间通信和共享数据的方式,这个缺点在一般程序的开发上不算个大问题,我们可以自己简单实现,但是对于GUI开发,这个缺点就被放大了很多倍。GUI上的对象实在太多,窗口是对象,布局是对象,定时器是对象,而且对象间有错综复杂的关系,通信和数据交换非常频繁,比如按钮按下要通知父窗口或容器对象,滚动条变化了要通知列表对象。这种数量庞大的对象以及复杂的通信关系,可不是自己搞个简单的实现就能解决的。

说到通信和共享,其实他们是一回事,共享很多时候就是为了通信,而C++里要通信就必然要共享。

比如,一个类实例拥有另一个的指针,就可以访问对方的数据,调用对方的方法了,这实际就是共享了一个指针,这个类指针也是另一个对象的this。访问数据和调用方法其实都是通信,把对方的数据拿过来,把自己的数据送过去,交换数据就是通信。

在C++里,由于没有GC,管理大量原生指针是极其危险的,对象的生命周期不可控,野指针的出现概率会很高,大型C++ 的GUI项目参与开发的人数众多,很难保证都不犯错。

那么发消息行不行呢?比如 MFC那样,可以,但是本质上还是共享了窗口句柄,否则消息发给谁呢?而且还带来另外的问题,就是类型安全,消息的参数是无法类型安全的。

Qt作为大型GUI项目的Framework,它必须解决这个问题,否则这个程序是写不大的,写大了就会问题层出不穷。

来看一段代码,看看Qt 的解决方案:

Window::Window()

{

QPushButton *b = new QPushButton(this);

connect(b, SIGNAL(clicked()), SLOT(on_button_clicked()));

}

Window::on_button_clicked()

{

QPushButton *b = qobject_cast<QPushButton*>(sender());

b->setText("clicked!");

}

这段代码,通过Qt的signal slot机制,把QPushButton的点击事件连接到了Window的on_button_clicked响应函数上。


3)布局管理

布局管理类用于描述一个应用程序的用户界面中的Widget是如何放置。当视窗缩放时,布局管理器会自动调整widget的大小、位置或是字号,确保他们相对的排列和用户界面整体仍然保有可用性。

Qt内置的布局管理类型有:QHBoxLayout、QVBoxLayout、QGridLayout和QFormLayout。这些类继承自QLayout,但QLayout非继承自QWidget而是直接源于QObject。他们负责widget的几何管理。想要创建更复杂的版面配置,可以继承QLayout来自定义版面配置管理员。

初识QT,你了解吗?

上图中被红框圈起来的,是页面中的布局,布局可以手写,我们这里只展示设计师中处理的布局。布局分为四种,我们这里用到了简单的两种,横向布局(QHBoxLayout)向布局(QVBoxLayout)。如上图所示。

到这里为止,只介绍了qt的一些基本的入门知识,大家通过qt的界面文件中的布局和信号处理,就可以完成一个简单的Qt小程序啦!