QT技术浅谈 作者:周伟 【详细,包括slot信号槽详解】

原文:http://express.ruanko.com/ruanko-express_55/tech-overnight1.html


一、QT介绍

1、什么是QT?

Qt是诺基亚开发的一个跨平台的C++图形用户界面应用程序框架。它提供给应用程序开发者建立艺术级的图形用户界面所需的所用功能。Qt很容易扩展,并且 允许真正地组件编程。基本上,Qt 同 X Window 上的 Motif,Openwin,GTK 等图形界面库和 Windows 平台上的MFC,OWL,VCL,ATL是同类型的东西。

2、QT的优势

1)优良的跨平台特性

Qt支持下列操作系统: Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS, HP-UX, Digital UNIX (OSF/1, Tru64), Irix, FreeBSD, BSD/OS, SCO, AIX, OS390,QNX 等等。

2)面向对象

Qt 的良好封装机制使得 Qt 的模块化程度非常高,可重用性较好,对于用户开发来说是非常方便的。Qt提供了一种称为 signals/slots 的安全类型来替代 callback,这使得各个元件之间的协同工作变得十分简单。

3)丰富的 API

Qt包括多达250个以上的 C++ 类,还提供基于模板的 collections、serialization、 file、I/O device、 directory management、 date/time 类。甚至还包括正则表达式的处理功能。

4)支持 2D/3D 图形渲染,支持 OpenGL

5)大量的开发文档

6)XML 支持

二、环境安装

因为我们要安装的版本是QT4.8支持VS2008开发环境的,所以要先安装VS2008。接下来,我们安装两个程序,如下图所示:

先安装“qt-win-opensource-4.8.2-vs2008.exe”,这个是支持Win平台下面VS2008的开源包;可以在“开始”->“程序”里面,出现下列内容:

然后再安装“qt-vs-addin-1.1.11-opensource.exe”,这个是VS2008的QT插件包,这样我们在VS2008下面就可以创建QT工程及进行开发了。安装成功后,会在VS环境下面出现下列内容:

三、QT环境介绍

安装了QT之后,我们要了解一下QT常用的几个程序的作用,如下图所示:

  • Assistant:这里面有QT类及函数的一些说明,类似于MSDN的帮助文档;
  • Designer:这个是QT的界面设计器,除了可以设计界面以后,还可以绑定相应的事件等非代码性的工作;
  • Examples and Demos:这个是QT的一些演示程序及文档说明。

四、QT学习

1、创建空白项目

项目组成:

不编写任何代码,按F5编译,界面显示:

我们按顺序来看一看相应的文件,来熟悉一下代码构成。

首先是main.cpp,众所周知,这个程序的入口,我们来看一下其中的代码:

然后是FirstQT.ui文件(前面过,项目编译后,会自动产生一个界面UI对应的类文件,也就是讲UI里面的内容以代码的形式进行存放):

窗口类的定义与实现:

firstqt.h文件

firstqt.cpp文件

通过这样的过程,对么对于界面如何显示出来的大致过程,应该有一定的了解了吧。下面我们再来讲一下如何设计界面,实现一些小的功能,那就要了解一下QT的Designer设计器了。

2、Designer设计

在VS开发环境下,双击“firstqt.ui”,则可进入QT的Designer编辑器进行界面设计,如下图所示:

下面我们在这个界面上添加三个控件,一个Label,一个滑动条vertical Slider,一个Spin Box,我们实现,滑动条进行上下拖动,然后在SpinBox和Label显示数值,界面大致如下所示:

接下来我们要实现相应的功能,就要使用Designer里面的“信号/槽”编辑模式下面,什么是信号/槽,这是QT里面很重要的一个概念,我们先实现这个功能后,再进行讲解。

在Designer里面选择“Edit”->“编辑信号/槽”,如下所示:

进入信号/槽的编辑模式,先左键选择vertical Slider,按着不动,将鼠标再点击spin box,如下图所示:

放开鼠标后,会弹出一个“配置连接”的界面,左边是vertical Slider控件的一些事件,右边是Spin Box控件的消息事件,左边选择valueChanged(int),右边选择“setValue(int)”,然后点击确定。

点击确定后,界面会出现下图中的情况,表示valueChanged(int)与setValue(int)进行了关联,也就是说,当vertical Slider的值发生改变的时候,会发送valueChanged这个信号,并且会由spin Box的setValue槽来进行接收,当然vertical Slider的值,也会被setValue所截获。

同样,我们设置一下SpinBox与Label之间的valueChanged信号与SetNum槽之间的绑定,如下图所示:

接下来,我们要在Desginer下面保存一下,然后在VS环境下面重新生成项目,这样在Designer下面修改的UI的内容,才会保存在ui_firstqt.h文件中。

生成后的内容如下:

那么到这里,我们就实现这样的一个小功能,在MFC里面,要写一些代码才能完成这样的功能,在QT里面可以很简单的实现。

那么下面,这个功能是怎么实现的,也就信号/槽是怎么回事。首先,我们要了解一下,我们在界面上面添加控件,添加信号/槽之后,添加了哪些代码。前面我们讲过,在UI里面设计的内容,都会在项目目录下面的“Generated Files”的ui_firstqt.h中,那么我们看一下其中发生了什么变化:

这里面关键的代码是这两句:

	
 QObject::connect(verticalSlider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
 QObject::connect(spinBox, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)));
 
 
 bool QObject::connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * member ) 

把从sender对象发送的signal和receiver对象中的member连接起来,并且如果连接成功返回真,否则返回假。 必须在说明signal和member的时候使用SIGNAL()和SLOT()两个宏。

另外signal和member。

信号和槽:

信号和槽用于对象之间的通信。信号槽机制是Qt的核心特性,并且很大程度上是区别去其他区别于其他框架提供的特性。

在GUI编程中,当一个widget改变,我们经常希望另外的widget被告知。更普遍地,我们希望任何的对象都可以互相通信。比如,如果用户点击close按钮,我们大多希望调用窗口的close()方法。

以前的工具集通过callback来实现这种通信。callback是指向函数的指针,因此,若果你想让处理函数通知你某些事件,你可以传递给另一个函数一个指针来处理函数。处理函数  在适当的时候调用callback。Callbacks有两种根本的缺陷:第一,它们不是类型安全的,我们无法确定处理程序会调用正确参数的回调函数(callback)。第二,回调函数耦合于处理函数,因为处理函数必须知道去调用哪个回调函数。

Qt提供了回调的替代技术:我们使用信号和槽。当特定事件发生时发出信号。Qt的widget有许多预定义的信号,但是我们可以为widget子类添加 我们自定义的信号。槽是回应特定的信号时所调用的方法。Qt的窗口部件有许多预定义的槽,但是我们也可以为窗口部件的子类田间我们自定义的槽,以处理我们 感兴趣的信号。

信号槽机制是类型安全的:信号的签名必须跟接受的槽的签名相匹配(事实上,槽的签名可以比信号的签名短,因为它可以忽略额外的 字段)。因为签名是相容的,编译器就可以帮我们检测类型的不匹配。信号和槽是松耦合的:一个类产生一个信号,并不知道而且不关心那个槽接受该信号。Qt的 信号槽机制保证,如果你连接了一对信号槽,槽会在适当的时间带着信号的参数被调用。信号和槽可以附带任何类型任何数量的参数。信号和槽是完全类型安全的。

所有的从QObject类继承的类或者说它的子类(比如,QWidget)可以包含信号槽。当对象改变状态的时候,可以以其他对象可能感兴趣的方式产生 信号。这就是所有的对象通信的方式。它不知道也不关心时候有对象接受它产生的信号。这是真正的信息封装,保证对象可以用作软件的组成部分。

槽可以用来接受信号,不过槽也是普通的成员函数。类似于对象不知道谁接受它的信号,槽也不知道是否有信号连接自己。这保证了Qt可以创建完全独立的组件。

一个信号可以连接无数的槽,并且一个槽可以连接你想要连接的信号。甚至可以直接连接两个信号(当第一个信号产生,立即产生第二个信号)。

信号和槽一起形成了一种强大的组件编程机制。

前面我们讲了如果给两个控件之间的信号与槽进行连接,那么下面,再讲一下,如何给个按钮添加一个处理事件。有两种方式,一种是代码添加,另一种是通过Designer的信号/槽模式进行编辑。

我们先讲第一种,如何用代码进行添加。前面我们虽然讲了UI会跟一个头文件ui_firstqt.h进行关联,就向上图所示,当信号与槽进行关联了,就会出现一些代码,但是我们不能在这个ui_firstqt.h人为添加代码,因为这个文件是在UI界面发生变化后,项目编译就会将UI的内容写到这个ui_firstqt.h文件中,如果你人为在其中添加代码,下次UI在Designer里面发生了改变,会把你手动添加的代码给全部覆盖。那么这些代码我们在哪里进行添加呢?

首先我们在Designer里面打开FirstQT.ui,然后添加一个pushButton,然后修改对象名,及文本内容。如下图所示:

然后在Designer里面保存,并关闭UI,重新生成项目,那么在ui_firstqt.h里面就会多出一个QPushButton的对象。因为这个文件是编译产生的,会被下次修改所覆盖,那么我们要添加我们自己的代码,就要在firstqt.h和firstqt.cpp里面进行添加。

首先,我们要添加一个槽,在firstqt.h添加下列代码:

	
private slots:
	void pushButtonM_Clicked();

备注:slots这个关键字,是槽的一个定义,只有这样定义了,才能被系统认定是一个槽,要不然是无法与信号进行绑定。

然后在firstqt.cpp添加以下代码:

编译运行,可以得到下面的结果:

MessageBox虽然弹出来了,但中文显示乱码,这是因为QT字符集默认是不支持中文的,如何解决呢?我们在Main函数里面添加下列代码来解决此事:

然后再运行,就可以显示中文了:

另一种为按钮的Clicked信号绑定槽的方式就是通过Designer的信号/槽编辑模式,下面在界面上添加一个PushButton,对象名称改为“pushButtonAuto”,文本显示改为“自动绑定”,然后进行信号/槽编辑中。在Designer菜单项->“Edit”->“编辑信号/槽”:

点击保存,然后重新在VS里面生成项目,会重新加载ui_firstqt.h,我们可以看到在这个文件里面的setupUi(QMainWindow *FirstQTClass)函数里面多了下列代码:

	
 QObject::connect(pushButtonAuto, SIGNAL(clicked()), FirstQTClass, SLOT(pushButtonAuto_Clicked()));

这样只是添加了绑定,我们还是要在FirstQT类里面添加pushButtonAuto_Clicked这个槽,如何定义,参考前面手动添加的代码。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值