使用QML并不需要Qt的知识,如果你已经熟悉Qt,那么很多知识都可以直接用于学习和使用QML.当然,使用QML定义UI的应用程序还是需要使用Qt实现非UI逻辑的.
熟悉的概念
QML直接支持如下Qt中的概念:
Extending QML Functionalities using C++以及Integrating QML Code with existing Qt UI code中需要Qt知识
QML项与QWidget比较
QML中的item与QWidget很相似:他们都定义了用户界面的外观.(注意通常QWidget并不是用来定义视图代理外观的,QML项也可这样使用.)
有三不同种结构的QWidget:
QML项也可这样分类.分类如下.
简单部件
最主要的原则是要记住当在C++中继承一个新的QDeclarativeItem类时不要定义任何的外观策略--留到QML使用元素时再定义.
作为范例,假设你要重用按钮项目.因此需要定义一个QDeclarativeItem子类实现按钮功能,与QToolButton继承于QWidget 一样,按上面的原则, QDeclarativeButton 类不应该有任何与外观相关的代码--只需要处理使能,触发等操作.
但这些已经被Qt中的QAction实现了.
QAction是UI无关的,可绑定到QPushButton, QCheckBox, QMenu,QToolButton,以及其他可视部件.
因此QML中以及具有了复选框功能--利用QAction.仅在QML中定义--按钮外观,状态的过度,如何精确的响应鼠标,键盘,或触摸输入.
为说明这点,请注意QDeclarativeTextEdit构建于QTextControl, QDeclarativeWebView构建于QWebPage,ListView 构建于QAbstractItemModel,QTextEdit, QWebView,和 QListView构建于UI无关的组件.
独立封装外观对QWidget是很重要的,QML中的组件概念也保留了这个观点.如果生成一个完整的应用程序,需要由一致的外观风格,需要创建一系列可重用的具有期望外观的组件.
为实现这个可重用按钮,需要简单的创建一个QML组件.
父部件
父部件提供了通用方法访问任意的子部件.QTabWidget 提供可访问多个页面(pages)的接口,同时只有一个page被显示,以及切换page的机制(QTabBar).QScrollArea 具有位于部件边缘的滚动条,可在有限的空间内浏览超大部件.
这些组件几乎都可以在QML中直接创建.只有几个对象需要特殊的事件处理,如Flickable,需要在C++中实现.
例如,假设要创建可大量用于应用程序中的一般的标签部件(tab widget),根据数据量判断是否需要分页显示.
QML组件和QWidget的parent概念最明显区别在于,子项位置是相对于父项的,但不会要求子项完全包含在父项中(当然可在必要时设置子项的clipped属性).这个差异具有深远的影响,例如:
组合部件
一些部件支持组合其他部件作为其实现细节,并为组合体提供高层次的API.例如QSpinBox 由一个QLineEdit和操作数值的向上向下按钮组成的.QFileDialog 作为一个完整的部件为用户提供查找和选择文件名称的功能.
开发可重用QML时,通常都是这样做的,使用已定义的item组合出新的item.
唯一需要注意的是,要考虑到使用组合体的用户可能希望采用动画和过度.例如,一个spinbox可能需要平滑过度到任意值,因此这个spinbox项需要由足够灵活,以允许这样的动画.
QML项与QGraphicsWidget比较
QML项和QGraphicWidget的主要不同点是使用方式.技术实现大致相同的,但实际上QML元素是可声明和可组合的,而QGraphicWidget是一个基本元素,用于协调QGraphicScene和部件.QML项和QGraphicWidget都从QGraphicsObject继承,可以共存.在布局系统中和与其他组件交互上是不同的.注意QGraphicWidget更倾向于要求在一个包中定义,而与QGraphicWidget等价的QML项可能由跨多个QML文件的QML项组合而成,但还是可以加载到C++的单个QGraphicsObject 对象中.
QGraphicsWidget通常使用QGraphicLayout来布局.QML不使用QGraphicLayout,因为Qt的布局对动画和UI的流畅性不太友好,因此几何上的接口是主要的不同点.当定义QML元素时,允许设计者使用绝对几何位置,绑定或描点(从QDeclarativeItem继承而来)定位其外边框,而不是使用布局或指定尺寸.如果适合指定尺寸就将其放置在QML文档中,让设计者知道如何更好的使用这个元素,但仍可完全控制界面外观.
其他主要不同在于QGraphicWidget用于布局模型,其具有独立的UI和逻辑.相反,QML实体通常是具有单一目标的项,不会在所有者中履行用户用例,而是在QML文件中组成等价的部件,要避免在项定义中涉及UI逻辑和组成可视化元素.而是尝试定义更加通用的实体,以便于在QML中定义界面外观(包括UI逻辑).
这两点不同决定了不同的交互方式. QGraphicsWidget是 QGraphicsObject的子类,用于在C++中轻松定义流畅的UI界面,而 QDeclarativeItem 是 QGraphicsObject 的子类用于在QML中定义流畅的UI界面.因此主要的不同是其暴露的接口,及设计时与其交互的对象(为QML声明实体,QGraphicWidget则不用如此,因为你需要在子类中定义UI逻辑)
如果希望同时使用QML和C++定义UI,例如要进行过度,推荐使用 QDeclarativeItem子类(也可同时使用QGraphicWidget).允许在C++中轻松的为每个C++组件创建一个根项 LayoutItem,向场景中加载独立的QML(可能定义在不同文件中,组成独立的UI和逻辑)代表的部件,替代个别的QGraphicWidget.