1.认识附加属性
QML有一个叫附加属性(AttachedProperties)的机制,在QML中默认提供了常用的Keys、Component等附加属性。
如下,我写了个按键的例子 ,因为默认只有获得焦点时才能触发按键事件,代码中我做了转发。
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Row{
spacing: 10
TextField {
width: 60
height: 30
text: "0"
Keys.onUpPressed: {
text=String(Number(text)+1)
}
//forwardTo属性提供了一种将按键,按键释放和来自输入法的键盘输入转发到其他项目的方法。
//当希望一个项目处理某些键(例如,向上和向下箭头键),
//而另一个项目处理其他键(例如,向左和右箭头键)时,此功能很有用。
//一旦已转发密钥的项目接受该事件,它将不再转发给列表中稍后的项目。
Keys.forwardTo: [box] //转发给id-root
}
TextField{
width: 60
height: 30
text: "0"
Keys.onUpPressed: {
text=String(Number(text)+1)
}
}
Rectangle{
id:box
width: 60
height: 30
color: "gray"
Keys.onPressed: {
color=Qt.hsla(Math.random(),1.0,0.5,1.0)
event.accepted=false;
}
}
}
}
那么什么是附加属性?为什么要有附加属性,而不是直接用属性(如Font)或者包含组件(如MouseArea)呢?
好吧,其实我也不明白为嘛要设计附加属性这个东西出来。但是可以想一下,如果没有附加属性,那些相关的功能该怎么实现呢?Keys可以像MouseArea那样设计,Component的属性和信号可以放到Item的实现中去,其他的一些附加属性也都可以作为属性或组件来替代。想到这里,我不由自主地流下了真正弱者的眼泪,等哪一天我领悟了这个设计的妙处再回来更新下。那一天,遥遥无期,就算等得到,青春也早已不在...(跑题了)
根据文档说明:
附加属性和附加信号处理程序是使对象能够使用其他属性或信号处理程序进行注释(annotate)的机制,而其他属性或信号处理程序对于对象是不可用的。特别是,它们允许对象访问与单个对象特别相关的属性或信号。
QML类型实现可以选择在C ++中创建具有特定属性和信号的附加类型。然后可以创建这种类型的实例,并在运行时将其附加到特定对象,从而允许那些对象访问附加类型的属性和信号。通过为属性和相应的信号处理程序添加前缀附加类型的名称来访问它们。
附加属性或处理程序的使用语法如下:
- <AttachingType>.<propertyName>
- <AttachingType>.on<SignalName>
2.实现附加属性
若是使用C++来扩展QML,要想实现一个附加属性的功能,需要两个步骤:
- 提供一个静态函数:static [类型] * qmlAttachedProperties(QObject *); 注意,这个返回类型可以是自身,也可以是关联的类型,参照官方示例attached,当你用 类型.属性 语法的时候只能用返回类型的属性;
- 使用宏声明该类型支持附加属性:QML_DECLARE_TYPEINFO([类型], QML_HAS_ATTACHED_PROPERTIES)
这里借用QtCreator中的示例attached(由于代码较长,我就不贴了,详情见官方示例源码):
这是一个非Ui的小例子,网上也有一些不完全的讲解。首先是BirthdayParty,他提供了静态函数和宏来支持附加属性,而静态函数返回的是BirthdayPartyAttached类型,BirthdayPartyAttached具有rsvp属性。但外单独定义了普通Person、Gril、Boy类并注册为QML类型。
有意思的来了,支持附加属性的类可以直接作为属性出现在对象中,而不是用 Type{ } 这种组件的方式组合起来。
import People 1.0
import QtQuick 2.0 // For QColor
BirthdayParty {
Boy {
name: "Robert Campbell"
BirthdayParty.rsvp: "2009-07-01"
}
Boy {
name: "Leo Hodges"
shoe { size: 10; color: "black"; brand: "Reebok"; price: 59.95 }
BirthdayParty.rsvp: "2009-07-06"
}
host: Boy {
name: "Jack Smith"
shoe { size: 8; color: "blue"; brand: "Puma"; price: 19.95 }
}
}
main.cpp的逻辑也很简单,就是判断/打印qml中那些属性的值,唯一要注意的是他使用了 QObject *attached = qmlAttachedPropertiesObject<BirthdayParty>(guest, false); 来获取组件的附加属性对象。
(如果没有理解可以仔细看看示例,或者看看别人的博客)
3.参考:
博客:https://www.jianshu.com/p/36ea29750398
博客:https://blog.csdn.net/ubuntukylin/article/details/9249633
博客:https://blog.csdn.net/weixin_33795833/article/details/85722645