Qt3升至Qt4需要注意的几件事项浅谈

公司以前的项目是用Qt3写的,随着时间的推移慢慢显示出Qt3有多方面的限制,因此先公司决定用Qt4来改写这个项目,并为软件添加新功能,在此背景先编写此文章。

先扯一下没用的:gotfocus是获得焦点时触发,Lostfocus是失去焦点的时候触发。比如:新建两个文本框,当点击第一个文本框的时候,则触发第一个文本框的getfocus事件,表示第一个文本框获得了焦点,可以进行操作了。然后鼠标点击第二个文本框的时候,第一个文本框首先触发lostfocus事件,标明它已经失去焦点,无法进行操作。同时第二个文本框获得焦点,允许输入数据进行操作

下面进入正题:


一、简介

Qt是一个跨平台的C++应用程序开发框架。广泛用于开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。

Qt使用标准的C++。通过语言绑定,其他的编程语言也可以使用Qt

Qt开放源代码,并且提供自由软件的用户协议。使得它可以被广泛地应用在各平台上的开放源代码软件开发中。Qt提供三种授权方式。三种授权方式的功能、性能都没有区别,仅在于授权协议的不同。LGPLGPL是免费发布,商业版则需收取授权费。

Qt商业版 - Qt商业授权适用于开发专属和/或商业软件。此版本适用于不希望与他人共享源代码,或者遵循GNU宽通用公共许可证(LGPL2.1版或GNU GPL 3.0版条款的开发人员。提供了技术支持服务。可以任意的修改Qt的源代码,而不需要公开。

GNU LGPL v. 2.1- Qt 4.5.0及以后的版本开始遵循GNU LGPLLGPL允许链结到它的软件使用任意的许可证,可以被专属软件作为类库引用、发布和销售。可以购买支持服务。

GNU GPL v. 3.0 - 如果您希望将Qt应用程序与受GNU通用公共许可证(GPL3.0版本条款限制的软件一同使用,或者您希望Qt应用程序遵循该GNU许可证版本的条款,则此版本Qt适用于开发此类Qt应用程序。可以购买支持服务。

Qt使用于OPIESkypeVLC media playerAdobe Photoshop ElementsVirtualBox 与 Mathematica以及被Autodesk、欧洲空间局、梦工厂、GoogleHPKDE、卢卡斯影业、西门子公司、富豪集团华特迪士尼动画制作公司、三星集团、飞利浦、Panasonic等所使用。

1. Qt4 版本简史:

   4.0 2005.06.28  支持 X11/Windows/Mac OS X/Embedded Linux

   4.1 2005.12.19  增加QtUiToolsQtTestQtSvg模块 

   4.2 2006.10.04  QGraphicsView取代QCanvas

   4.3 2007.05.30  增加QtScript

   4.4 2008.05.06  增加PhononWebKit,全新的QtHelp模块,开始支持wince平台

   4.5 2009.03.03  添加LPGL授权,ActivQt模块在Qt4.5.2才实现了在LPGL版中可用

   4.6 2009.12.01  所有源码统一成一份,qt everywhere,开始支持Symbian平台

   4.7 2010.09.21  增加QtDeclarative模块,增加QML

   ……

2. Qt4模块:

  QtCoreQt提供的非GUI核心类库。 

  QtGui,图形用户界面组件。

  QtMultimedia,多媒体支持。

  QtNetwork,网络支持。

  QtOpenGL,提供对OpenGL 的支持。

  QtOpenVG,提供对OpenVG 的支持。

  QtScript,提供对Qt Scripts的支持。Qt Script是一种类似于JavaScript的脚本语言。

  QtScriptTools,为Qt Script提供的额外组件。

  QtSql,提供对SQL数据库的支持。

  QtSvg,提供对SVG文件的支持。

  QtWebKit,提供显示和编辑Web内容。

  QtXmlXML处理。

  QtXmlPatterns,提供对XQueryXPath等的支持。

  QtDeclarative,用于编写动画形式的图形用户界面的引擎。

  Phonon,多媒体框架。

  Qt3SupportQt3兼容类库。

   Qt4的工具模块:

  QtDesigner,用于扩展Qt Designer

  QtUiTools,用于在自己的引用程序中处理Qt Designer生成的form文件。

  QtHelp,联机帮助。

  QtTest,单元测试。

  3. 常用对象

  QWidgetQFrameQDialogQPushButtonQMenuQTableViewQTreeViewQListView等。常用对话框类:

  QColorDialog:选择颜色;

  QFileDialog:选择文件或者目录;

  QFontDialog:选择字体;

  QInputDialog:允许用户输入一个值,并将其值返回;

  QMessageBox:模态对话框,用于显示信息、询问问题等;

  QPageSetupDialog:为打印机提供纸张相关的选项;

  QPrintDialog:打印机配置;

  QPrintPreviewDialog:打印预览;

  QProgressDialog:显示操作过程。

   更多请参考Qtassistantqdoc

   变化历史请参阅qthelp://com.trolltech.qt.483/qdoc/qt4-8-intro.html

二、编程相关

0. C++语言标准本身是不区分跨平台的,Qt是跨平台的C++类库实现,C/C++有的尽量不用Qt的实现,特别是非界面程序。

 Qt是可‘剪裁’的,所实现的模块比较多,需要什么功能才去引用对用的模块,这点儿与MFC不同。C++的容器类,在Qt中有对应的实现,对于后台服务等不带界面的程序,不建议使用Qt的功能方法,以避免引入Qt的库。

1. Qt工具

Qt Designer: 界面设计工具,所见即所得,支持layout, 支持signal/slot编辑。 生成的文件保存为ui格式, uixml格式的普通文本文件, 默认编码为utf8

Qt Assistant: QtAPI帮助文档查看工具, 支持html的子集(图片、超链、文本着色), 支持目录结构、关键字索引和全文搜索,是Qt编程必备、使用率最高的工具。

Qtdemo: Qt例子和演示程序的加载器,用于查看Qt提供的例子程序,不仅可以看到程序运行的情况,还可以查看源码和文档

Qmake: 用于生成Makefile的命令行工具。读取Qt本身的配置(平台配置、pro文件), 为程序生成与库一致的Makefile。 它是Qt跨平台编译系统的基础。

Qt Linguist: Qt语言家的,用于界面国际化,主要任务只是读取翻译文件、为翻译人员提供友好的翻译界面。 Linguist必须要和其他工具一起用才能完成Qt国际化。

Lupdate:国际化的命令行工具之一, 它的功能是从源码文件或其他资源文件中提取需要翻译的字符串,并将之用正确的编码和格式存入tsxml格式)文件中。 

Lrelease: 国际化的命令行工具之一, 它负责将ts文件转化为程序使用的qm文件。 转化过程最大的变化是去掉了原始文件中所有的空白和未翻译的内容, 并将存储格式压缩。

UicUI Compiler命令行工具是,用来编译ui文件,把ui文件转化为编译器可以识别的标准C++文件, 生成的文件是一个.h

MocMeta Object Compiler元对象编译器(预编译工具), 用来生成与信号和槽相关的底层代码。 该工具处理带有Q_OBJECT宏的头文件, 生成形如moc_xxx.h, moc_xxx.cppC++代码,之后再与程序的代码一同编译。

RccResource Compiler资源文件编译工具,根据资源定义qrc文件的内容将相关的文件编译为二进制,并与源码编译在一起,保存在应用程序的二进制文件中。

QtconfigX11系统下用于配置Qt环境的工具。 可以设定字体、StylePalette、打印机等。 设定信息保存在用户目录。

2. designerlayout

Qt3designer可以编辑代码并管理工程,Qt4designer相对弱化了,主要是设计界面元素。以下二图大致描述了两者的区别:

designer提供了信号槽关联功能,还是建议在自己的程序代码里实现信号与槽的关联。

如果需要固定窗体大小,可以设置窗体属性实现。不建议使用绝对坐标固定窗体内的控件位置,尽量使用布局管理窗体内控件,以避免由于国际化而使得界面元素/信息显示不全。

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

Qt自带的布局管理类型有:QHBoxLayoutQVBoxLayoutQGridLayoutQFormLayout。这些类型继承自QLayout,但QLayout非继承自QWidget而是直接源于QObject。它们负责widget的几何管理。

QHBoxLayout:配置widget成横向一列

QVBoxLayout:配置widget成垂直一行

QGridLayout:配置widget在平面网格

QFormLayout:配置widget用于2栏标签- field

设计界面时,先创建各个控件,然后设置layout

QGridLayout对设置布局前的窗口布局依赖比较大,设计布局前可以先将界面控件大致按照预想的布局排列一下,再应用布局。

QGridLayout包含多个grid,通常情况下,每个gridsize是不同的,在其中添加的widget在垂直或水平方向上可跨越或者占据多少个grid

ui制作时注意,ui文件命名影响代码中引用该ui的头文件名,如uidialog.ui -> ui_uidialog.h以及ui_uidialog.cppui窗体的类名影响代码中该ui生成的C++类的名称,如uidialog.ui的类名属性为NormalDialog,生成界面类Ui_NormalDialogUi::NormalDialog

3. signal/slot

可以简单的认为一个调用点(信号)与零个或者多个‘回调’(槽函数)相连。

信号槽这一术语最初来自 Trolltech 公司的 Qt 库。1994Qt 的第一个版本发布,带来了信号槽的概念,如今信号槽依然是 Qt 库的核心之一。其他许多库(如boost)也提供了类似的实现。

相比于直接函数调用(回调),信号槽比较安全,但是一个信号槽的调用,可能会耗费更多的时间/空间,同时不能使用 inline,但是却增加了灵活性。

槽的关联(connect)与删除(disconnect)可以是动态的。

一个信号可以关联多个槽,各个槽按照被connect的顺序被执行(Qt 4.6之前执行顺序不确定),但最好不要期望其顺序执行!

   槽是普通的c++成员函数,可以是虚函数,也可以被重载,可以是公有的,保护的或私有的,可以传递任何类型的参数,可以有返回值,在信号触发槽函数时,返回值被忽略。

   如果信号的参数比它所连接的槽的参数多,信号中多余的参数会被忽略掉。建议SIGNALSLOT使用相同的参数。

   要避免槽中再次发射所接收到的同样信号(死循环)。

QSignalMapper类:用于多个信号(signal)连接到同一个槽(slot),而这个槽又需区别处理每个信号的情况。QSignalMapper类收纳了一个无参数的信号集,然后相应于原发射信号的对象用整型、字符串或widget参数进行信号重发。QSignalMapper::setMapping()方法用于映射所有widget的信号到单个QSignalMapper对象。而删除映射可以用QSignalMapper::removeMappings()方法。然后widget的信号连接到QSignalMapper::map()槽。最后,QSignalMapper::mapped()信号连接到任何自定义widgetsingal/slot做需要的处理。

4. 国际化

不建议程序里需要显示在界面的内容直接使用中文,不建议直接在ui界面上使用中文(尽管designer支持这样做),尽量使用翻译文件做中文化处理。

Qt类中的多语言处理可以使用QObject::tr()翻译,或者自定义一个类(从QObject派生)来处理。

中文国际化翻译文件的名称格式最好能够统一,如中文翻译文件名:[模块名称]_zh.qm,以便于管理及程序运行时的语言切换。建议翻译文件和二进制文件在同一目录下。

QT中所有的字符串都是用Unicode编码的.如果我们有一个本地编码系统的字符串的话,我们可以简单的通过QString::fromLocal8Bit()QString::toLocal8Bit().data()进行转换。在Windows平台下这些都是没有问题的,但是在QT4.1.1的版本以后,UNIX平台这样的转换会造成出现很多的乱码。出现这个问题的原因是QT不能得到正确的本地编码类型,所以需要强制设定一下。例如:

QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));

5. 资源文件

主要是程序使用的图标,建议使用png格式(能够确保在不同的平台上有一致的显示效果)并使用Qt提供的资源管理方案。文件名的后缀使用小写png

模块的资源文件爱你统一放置在[安装目录]\资源文件目录\[模块名称]下,便于管理。

6. Q_OBJECT/Q_PROPERTY

Q_OBJECT宏,生成一个包含元对象代码的C++源文件,元对象代码对信号/槽机制、运行时类型信息和动态属性系统是需要的。

Q_PROPERTY宏用于声明了对象属性,如:

Q_PROPERTY( Priority priorityREAD priority WRITE setPriority )

void setPriority( Priority );

Priority priority() const;

 如果程序中的某个类使用了信号槽或者其它的Qt特性,编译时遇到Meta-Object相关错误,多数与没有使用Q_OBJECT宏有关,使用Q_OBJECT宏并重新qmake后即可解决。

    包含Q_OBJECT的代码(*.h *.cpp) 在构建过程中会被预编译为 moc_*.cpp, *.moc

7. 插件支持

Qt有两种与插件有关的API。一种用来扩展Qt本身的功能,如自定义数据库驱动,图像格式,文本编解码,自定义分格,等等,称为Higher-Level API。另一种用于应用程序的功能扩展,称为Lower-Level API。前一种是建立在后一种的基础之上的。

基本上我们不需要扩展Qt本身的功能,对我们有用的是后一种,即用来扩展应用程序的Lower-level API

让应用程序支持插件扩展的步骤:

a. 定义一个接口集(只有纯虚函数的类),用来与插件交流。

b. 用宏Q_DECLARE_INTERFACE()将该接口告诉Qt元对象系统,如:

Q_DECLARE_INTERFACE(BrushInterface,"com.shr.plugin.hmi/1.0")

c. 应用程序中用QPluginLoader来装载插件。

d. 用宏qobject_cast()来确定一个插件是否实现了接口。

 QObject *obj = new QTimer;

QTimer *timer = qobject_cast<QTimer *>(obj);

写一个插件的步骤:

a. 声明插件类,该类从QObject和该插件希望实现的接口继承而来。

b. 用宏Q_INTERFACES()将该接口告诉Qt元对象系统。

class BasicToolsPlugin : public QObject, public BrushInterface,

  public ShapeInterface, public FilterInterface

{

Q_OBJECT

Q_INTERFACES(BrushInterface ShapeInterface FilterInterface)

public:

...

};

c. 用宏Q_EXPORT_PLUGIN2()导出插件。

Q_EXPORT_PLUGIN2 ( PluginName, ClassName )

d. 用适当的.pro文件构建插件。

8. Model/View

Model-View-Controller(MVC)由三种对象组成,Model是应用程序对象,View是它的屏幕表示,Controller定义了用户界面如何对用户输入进行响应。

viewcontroller结合在一起,就是model/view结构,与MVC都基于同样的思想,但它更简单一些。这种分离使得在几个不同的view上显示同一个数据成为可能,也可以重新实现新的view,而不必改变底层的数据结构。

为了更灵活的对用户输入进行处理,引入了delegate这个概念(QItemDelegate对象)。它的好处是,数据项的渲染(绘制方式)与编程可以进行定制,主要用于表格、树或列表的对象显示及编辑方式。如下图所示:

model与数据源通讯,并提供接口给别的组件使用。通讯的性质依赖于数据源的种类与model实现的方式。viewmodel获取model indexes,后者是数据项的引用。通过把model indexes提供给modelview可以从数据源中获取数据。在标准的views中,delegate会对数据项进行渲染,当某个数据项被选中时,delegate通过model indexesmodel直接进行交流。

model/view 相关类可以被分成上面所提到的三组:modelsviewsdelegates。这些组件通过抽象类来定义,它们提供了共同的接口(在某些情况下,还提供了缺省的实现)。抽象类意味着允许实现定制的组件,子类化以提供完整的其他组件希望的功能。Modelsviewsdelegates之间通过信号/槽机制来进行通讯:

l 从model发出的信号通知view数据源中的数据发生了改变。

l 从view发出的信号提供了有关被显示的数据项与用户交互的信息。

l 从delegate发生的信号被用于在编辑时通知modelview当前编辑器的状态信息。

所有的item models都基于QAbstractItemModel类,这个类定义了用于viewsdelegates访问数据的接口。QAbstractItemModel提供给数据接口,QAbstractListModelQAbstractTableModel是其针对tablelist的实例类。QT提供了一些现成的models用于处理数据项:

QStringListModel 用于存储简单的QString列表。

QStandardItemModel 管理复杂的树型结构数据项,每项都可以包含任意数据。

QDirModel 提供本地文件系统中的文件与目录信息。

QSqlQueryModelQSqlTableModelQSqlRelationTableModel用来访问数据库。

如果标准Model不满足你的需要,应该子类化QAbstractItemModelQAbstractListModel或是QAbstractTableModel来定制。

基于QAbstractItemView抽象基类:QListView把数据显示为一个列表,QTableViewModel 中的数据以table的形式表现,QTreeView 用具有层次结构的列表来显示model中的数据。功能不满足要求时,可以子类化以便满足定制需求。

QAbstractItemDelegate model/view架构中的用于delegate的抽象基类。缺省的delegate实现在QItemDelegate类中提供。

model/view架构中,重新实现QAbstractItemModel::sort()函数来来支持排序。QTableViewQTreeView都提供了默认API,允许以编程的方式对Model数据进行排序。

假如model没有提供需要的接口或是你想用list view表示数据,可以用一个代理model在用view表示数据之前对你的model数据结构进行转换。

为与Qt 3兼容, QListWidgetQTreeWidgetQTableWidget等提供了如Qt 3中的QListBoxQlistViewQTable相似的行为。但比着View类缺少灵活性,所以不建议直接使用QListWidgetQTreeWidgetQTableWidget等,应尽量使用对应Model/View来替代。

9. 内存管理

所有继承自QOBJECT类的类,如果在new的时候指定了父亲,在父亲被delete的时候它会被delete,所以如果一个程序中,所有的QOBJECT类都指定了父亲,那么他们是会一级级的在最上面的父亲清理时被清理,而不用自己清理。

程序通常最上层会有一个根的QOBJECT,(放在setCentralWidget中的那个QOBJECT),这个QOBJECTnew的时候不必指定它的父亲(它的父亲为QAPPLICATION),程序退出时会被自动清理。除此以外,对没有父亲的QWidget派生类对象,需要自己维护其生命周期或者使用setAttribute(Qt::WA_DeleteOnClose)

   QT中建议不要直接delete掉一个QOBJECT对象,为避免意想不到的内存错误,界面QWidget及其派生类对象尽量通过new分配在heap中,而不是在stack中。

QT不建议在一个QOBJECT 的父亲的范围之外持有对这个QOBJECT的指针(如果这样外面的指针很可能不会察觉这个QOBJECT被释放,会出现错误),如果要这样在外部持有QOBJECT的指针,建议使用引用或者用智能指针。

10. QWidget

 QWidget类是所有用户界面对象的基类。QWidget的方法全部都掌握了,使用Qt库编写界面程序会变得十分容易。

 通常情况下,顶级窗口部件是有框架和标题栏的窗口,一个没有父窗口部件的窗口部件一直是顶级窗口部件。 QMainWindow和不同的QDialog的子类是最普通的顶级窗口。

非顶级窗口部件是子窗口部件。它们是其父窗口部件中的子窗口,可以简单的认同为控件。在Qt中的绝大多数其它窗口部件仅仅作为子窗口部件才是有用的。(当然把一个按钮作为或者叫做顶级窗口部件也是可能的,但绝大多数人喜欢把他们的按钮放到其它按钮当中,比如QDialog。)

QWidget有很多成员函数,但是它们中的一些有少量的自己从来不用的直接功能(如,字体属性),有很多继承它的子类提供了实际的功能,比如QPushButtonQListBoxQTabDialog等。

QWidget的成员函数分组: 

上下文  函数 

窗口函数  show()hide()raise()lower()close()

顶级窗口  caption()setCaption()icon()setIcon()iconText()setIconText()isActiveWindow()setActiveWindow()showMinimized()showMaximized()showFullScreen()showNormal()

窗口内容  update()repaint()erase()scroll()updateMask()

几何形状  pos()size()rect()x()y()width()height()sizePolicy()setSizePolicy()sizeHint()updateGeometry()layout()move()resize()setGeometry()frameGeometry()geometry()childrenRect()adjustSize()mapFromGlobal()mapFromParent()mapToGlobal()mapToParent()maximumSize()minimumSize()sizeIncrement()setMaximumSize()setMinimumSize()setSizeIncrement()setBaseSize()setFixedSize()

模式  isVisible()isVisibleTo()visibleRect()isMinimized()isDesktop()isEnabled()isEnabledTo()isModal()isPopup()isTopLevel()setEnabled()hasMouseTracking()setMouseTracking()isUpdatesEnabled()setUpdatesEnabled()

观感  style()setStyle()cursor()setCursor()font()setFont()palette()setPalette()backgroundMode()setBackgroundMode()colorGroup()fontMetrics()fontInfo()

键盘焦点函数 isFocusEnabled()setFocusPolicy()focusPolicy()hasFocus()setFocus()clearFocus()setTabOrder()setFocusProxy()

鼠标和键盘捕获  grabMouse()releaseMouse()grabKeyboard()releaseKeyboard()mouseGrabber()keyboardGrabber()

事件处理器  event()mousePressEvent()mouseReleaseEvent()mouseDoubleClickEvent()mouseMoveEvent()keyPressEvent()keyReleaseEvent()focusInEvent()focusOutEvent()wheelEvent()enterEvent()leaveEvent()paintEvent()moveEvent()resizeEvent()closeEvent()dragEnterEvent()dragMoveEvent()dragLeaveEvent()dropEvent()childEvent()showEvent()hideEvent()customEvent()

变化处理器  enabledChange()fontChange()paletteChange()styleChange()windowActivationChange()

系统函数  parentWidget()topLevelWidget()reparent()polish()winId()find()metric()

这是什么的帮助  customWhatsThis()

内部核心函数  focusNextPrevChild()wmapper()clearWFlags()getWFlags()setWFlags()testWFlags()

每一个窗口部件构造函数接受两个或三个标准参数: 

QWidget *parent = 0是新窗口部件的父窗口部件。如果为0(默认),新的窗口部件将是一个顶级窗口部件。如果不是,它将会使parent的一个孩子,并且被parent的几何形状所强迫(除非你指定WType_TopLevel作为窗口部件标记)。

const char *name = 0是新窗口部件的窗口部件名称。你可以使用name()来访问它。窗口部件名称很少被程序员用到,但是对于图形用户界面构造程序,比如Qt设计器,是相当重要的(你可以在Qt设计器中命名一个窗口部件,并且在你的代码中使用这个名字来连接它)。dumpObjectTree()调试函数也使用它。

WFlags f = 0(在可用的情况下)设置窗口部件标记,默认设置对于几乎所有窗口部件都是适用的,但是,举例来说,一个没有窗口系统框架的顶级窗口部件,你必须使用特定的标记。

QWidget的常用事项处理函数: 

paintEvent() - 只要窗口部件需要被重绘就被调用。每个要显示输出的窗口部件必须实现它并且不在paintEvent()之外在屏幕上绘制是明智的。 

resizeEvent() - 当窗口部件被重新定义大小时被调用。 

mousePressEvent() - 当鼠标键被按下时被调用。有六个鼠标相关事件,但是鼠标按下和鼠标释放事件是到目前为止最重要的。当鼠标在窗口部件内或者当它使用grabMouse()来捕获鼠标时,它接收鼠标按下事件。

mouseReleaseEvent() - 当鼠标键被释放时被调用。当窗口部件已经接收相应的鼠标按下事件时,它接收鼠标释放事件。这也就是说如果用户在你的窗口部件内按下鼠标,然后拖着鼠标到其它某个地方,然后释放,你的窗口部件接收这个释放事件。这里有一个例外:如果出现在弹出菜单中,当鼠标键被按下时,这个弹出菜单立即会偷掉这个鼠标事件。

mouseDoubleClickEvent() - 和它看起来也许不太一样。如果用户双击,窗口部件接收一个鼠标按下事件(如果他们没有拿牢鼠标,也许会出现一个或两个鼠标移动事件)、一个鼠标释放事件并且最终是这个事件。直到你看到第二次点击是否到来之前,不能从一个双击中辨别一个点击。(这是为什么绝大多数图形用户界面图书建议双击是单击的一个扩展,而不是一个不同行为的触发的一个原因。)

如果你的窗口部件仅仅包含子窗口部件,你也许不需要实现任何一个事件处理器。如果你想检测在子窗口部件中的鼠标点击,请在父窗口部件的mousePressEvent()中调用子窗口部件的hasMouse()函数。

接收键盘的窗口部件需要重新实现一些更多的事件处理器: 

keyPressEvent() - 只要键被按下和当键已经被按下足够长的时间可以自动重复了就被调用。注意如果TabShift+Tab键被用在焦点变换机制中,它们仅仅被传递给窗口部件。为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget::event()

focusInEvent() - 当窗口部件获得键盘焦点(假设你已经调用setFocusPolicy())时被调用。写得好的窗口部件意味着它们能按照一种清晰但谨慎的方式来获得键盘焦点。

focusOutEvent() - 当窗口部件失去键盘焦点时被调用。 

一些窗口部件也许需要实现一些不太普通的事件处理器: 

mouseMoveEvent() - 只要当鼠标键被按下时鼠标移动就会被调用。举例来说,对于拖动,这个很有用。如果你调用setMouseTracking(TRUE),尽管没有鼠标键被按下,你也会获得鼠标移动事件。(注意这个使用鼠标跟踪的应用程序在低下的X连接下不是很有用。)(也可以参考拖放信息。)

keyReleaseEvent() - 只要键被释放和当如果这个键是自动重复的并且被按下一段时间时就被调用。在这种情况下窗口部件接收一个键释放事件并且对于每一个重复立即有一个键按下事件。注意如果TabShift+Tab键被用在焦点变换机制中,它们仅仅被传递给窗口部件。为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget::event()

wheelEvent() -- 当窗口部件拥有焦点时,只要用户转动鼠标滚轮就被调用。 

enterEvent() - 当鼠标进入这个窗口部件屏幕空间时被调用。(这不包括被这个窗口部件的子窗口部件所拥有的屏幕空间。) 

leaveEvent() - 当鼠标离开这个窗口部件的屏幕空间时被调用。 

moveEvent() - 当窗口部件相对于它的父窗口部件已经被移动时被调用。 

closeEvent() - 当用户关闭窗口部件时(或这当close()被调用时)被调用。 

当实现一个窗口部件时,还有一些更多的事情要考虑。 

l 在构造函数中,在你可能收到一个事件的任何机会之前,请确认尽早地设置你的成员变量。 

l 重新实现sizeHint()在绝大多数情况下都是很有用的并且使用setSizePolicy(),来设置正确的大小策略,这样可以更容易地设置布局管理器。一个大小策略可以让你为布局管理器提供好的默认情况,这样其它窗口部件可以很容易地包含和管理你的窗口部件。sizeHint()为这个窗口部件说明一个“好的”大小。

l 如果你的窗口部件是一个顶级窗口部件,setCaption()setIcon()分别设置标题栏和图标。 

11. 动态库导出QWidget界面窗口类

可以通过动态库导出Qt的界面类(QWidget派生类),就跟QtGui导出的界面类一样。

实例:

  #ifndef QMYWIDGET_H

 #define QMYWIDGET_H

 #include <QtGui/QWidget>

 #if defined(QMYWIDGET_LIBRARY)

 #  define QMYWIDGETSHARED_EXPORT Q_DECL_EXPORT

 #else

 #  define QMYWIDGETSHARED_EXPORT Q_DECL_IMPORT

 #endif

 namespace Ui {    class Form;   }

 class QMYWIDGETSHARED_EXPORT QMyWidget : public QWidget

 {

      Q_OBJECT

 public:

      QMyWidget(QWidget *parent=0);

 private:

      Ui::Form *m_form;

 }; 

#endif // QMYWIDGET_H

如上例,界面类使用了ui对象,使用事先声明避免在导出类的声明头文件中包含ui对应的头文件(使用ui对象指针)。

12. QtCreator

 Qt4在诺基亚的管理期间得到了迅速的发展。同时诺基亚对Qt的一个很大的贡献是组织开发了QtCreator

QtCreator支持C/C++/QtQML开发,能很好的发挥Qt 跨平台的特点。在任何平台上,只要能够编译Qt,那么使用QtCreator便不是问题—因为它是使用Qt开发的。

13. Qt User Interface Creation Kit

   Qt Quick2将使用Scene Graph,更好地发挥GPU的性能;QML建立在Scene Graph的基本结构之上

14. Qt5

基础模块:

Qt Core,提供核心的非 GUI 功能,所有模块都需要这个模块。

这个模块的类包括了动画框架、定时器、各个容器类、时间日期类、事件、IOJSON、插件机制、智能指针、图形(矩形、路径等)、线程、XML 等。所有这些类都可以通过 <QtCore> 头文件引入。

Qt Gui,提供 GUI 程序的基本功能,包括与窗口系统的集成、事件处理、OpenGL 和 OpenGL ES 集成、2D 图像、字体、拖放等。

这些类一般由 Qt 用户界面类内部使用,当然也可以用于访问底层的 OpenGL ES 图像 API

Qt Gui 模块提供的是所有图形用户界面程序都需要的通用功能。

Qt Multimedia,提供视频、音频、收音机以及摄像头等功能。

这些类可以通过 <QtMultimedia> 引入,而且需要在 pro 文件中添加 QT += multimedia

Qt Network,提供跨平台的网络功能。

这些类可以通过 <QtNetwork> 引入,而且需要在 pro 文件中添加 QT += network

Qt Qml,提供供 QML(一种脚本语言,也提供 JavaScript 的交互机制) 使用的 C++ API

这些类可以通过 <QtQml> 引入,而且需要在 pro 文件中添加 QT += qml

Qt Quick,允许在 Qt/C++ 程序中嵌入 Qt Quick(一种基于 Qt 的高度动画的用户界面,适合于移动平台开发)。

     这些类可以通过 <QtQuick> 引入,而且需要在 pro 文件中添加 QT += quick

Qt SQL,允许使用 SQL 访问数据库。

        这些类可以通过 <QtSql> 引入,而且需要在 pro 文件中添加 QT += sql

Qt Test,提供 Qt 程序的单元测试功能。

        这些类可以通过 <QtTest> 引入,而且需要在 pro 文件中添加 QT += testlib

Qt Webkit,基于 WebKit2 的实现以及一套全新的 QML APIQt 4.8 附带的是 QtWebkit 2.2)。

扩展模块:

Qt 3D,提供声明式语法,在 Qt 程序中可以简单地嵌入 3D 图像。

Qt 3D 为 Qt Quick 添加了 3D 内容渲染。Qt 3D 提供了 QML 和 C++ 两套 API,用于开发 3D 程序。

Qt Bluetooth,提供用于访问蓝牙无线设备的 C++ 和 QML API

Qt Contacts,用于访问地址簿或者联系人数据库的 C++ 和 QML API

Qt Concurrent,封装了底层线程技术的类库,方便开发多线程程序。

Qt D-Bus,这是一个仅供 Unix 平台使用的类库,用于利用 D-Bus 协议进行进程间交互。

Qt Graphical Effects,提供一系列用于实现图像特效的类,比如模糊、锐化等。

Qt Image Formats,支持图片格式的一系列插件,包括 TIFFMNGTGA 和 WBMP

Qt JS Backend,该模块没有公开的 API,是 V8 JavaScript 引擎的一个移植。这个模块仅供 QtQml 模块内部使用。

Qt Location,提供定位机制、地图和导航技术、位置搜索等功能的 QML 和 C++ API

Qt OpenGL,方便在 Qt 应用程序中使用 OpenGL

     该模块仅仅为了程序从 Qt 4 移植到 Qt 5 的方便才保留下来,

如果你需要在新的 Qt 5 程序中使用 OpenGL 相关技术,需要使用的是 QtGui 模块中的 QOpenGL

Qt Organizer,使用 QML 和 C++ API 访问组织事件(organizer event)。

organizer API 是 Personal Information Management API 的一部分,用于访问 Calendar 信息。通过 Organizer API 可以实现:从日历数据库访问日历时间、导入 iCalendar 事件或者将自己的事件导出到 iCalendar

Qt Print Support,提供对打印功能的支持。

Qt Publish and Subscribe,为应用程序提供对项目值的读取、导航、订阅等的功能。

Qt Quick 1,从 Qt 4 移植过来的 QtDeclarative 模块,用于提供与 Qt 4 的兼容。

        如果你需要开发新的程序,需要使用 QtQuick 模块。

Qt Script,提供脚本化机制。这也是为提供与 Qt 4 的兼容性,如果要使用脚本化支持,请使用 QtQml 模块的 QJS* 类。

Qt Script Tools,为使用了 Qt Script 模块的应用程序提供的额外的组件。

Qt Sensors,提供访问各类传感器的 QML 和 C++ 接口。

Qt Service Framework,提供客户端发现其他设备的服务。

Qt Service Framework 为在不同平台上发现、实现和访问服务定义了一套统一的机制。

Qt SVG,提供渲染和创建 SVG 文件的功能。

Qt System Info,提供一套 API,用于发现系统相关的信息,比如电池使用量、锁屏、硬件特性等。

Qt Tools,提供了 Qt 开发的方便工具,包括 Qt CLuceneQt DesignerQt Help 以及 Qt UI Tools 

Qt Versit,提供了对 Versit API 的支持。

        Versit API 是 Personal Information Management API 的一部分,

        用于 QContacts 和 vCard 以及 QOrganizerItems 和 iCalendar 之间的相互转换。

Qt Wayland,仅用于 Linux 平台,用于替代 QWS,包括 Qt Compositor APIserver)和 Wayland 平台插件(clients)。

Qt WebKit,从 Qt 4 移植来的基于 WebKit1 和 QWidget 的 API

Qt Widgets,使用 C++ 扩展的 Qt Gui 模块,提供了一些界面组件,比如按钮、单选框等。

Qt XMLSAX 和 DOM 的 C++ 实现。该模块已经废除,请使用 QXmlStreamReader/Writer

Qt XML Patterns,提供对 XPathXQueryXSLT 和 XML Schema 验证的支持。

第三方资源

 QCharts is a part of Qt Commercial addons package. It provides a set of easy to use chart components which are available for Qt Commercial customers. It uses Qt Graphics View Framework, therefore charts can be easily integrated to modern user interfaces. QCharts can be used as QWidgets, QGraphicsWidget or QML elements. Users can easily create impressive graphs by selecting one of the charts themes.

QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目, 可生成各种统计图。它为具有技术专业背景的程序提供GUI组件和一组实用类,其目标是以基于2D方式的窗体部件来显示数据, 数据源以数值,数组或一组浮点数等方式提供, 输出方式可以是Curves(曲线),Slider(滚动条),Dials(圆盘),Compasses(仪表盘)等等。该工具库基于Qt开发,所以也继承了Qt的跨平台特性。

KD Chart is a tool for creating business charts and is the most powerful Qt component of its kind. Besides having all the standard features, it enables the developer to design and manage a large number of axes and provides sophisticated customization. 

KD Chart utilizes the Qt Model-View programming model and allows for re-use of existing data models to create charts. KD Chart is a complete implementation of the ODF (OpenDocument) Chart specification. It now includes Stock Charts, Box & Whisker Charts and the KD Gantt module for implementing ODF Gantt charts into applications.

QicsTable is a full-featured, high-performance, Qt-based table widget suited for use in industrial-strength applications. It provides unparalleled performance, scalability and flexibility. 

KD ReportsWith KD Reports, you can add high-quality reporting to your Qt applications. KD Reports accesses your application data and uses a programmer-provided page description in order to generate good-looking reports, including automated page-breaking for multi-page reports.KD Reports supports automatic and custom tables, variable headers and footers, as well as text and image elements. An easy-to-use built-in layout engine gives you flexibility for arranging your reports.

  

学习资源:最好的是Qt自带的assistantexample

   以下参考网站:

   http://blog.qt.digia.com/ 

   http://www.cuteqt.com/blog/ 

   http://blog.csdn.net/dbzhang800 

   http://hi.baidu.com/new/dbzhang800

……







猜你喜欢

转载自blog.csdn.net/Devil_box/article/details/44782199
qt4
今日推荐