Qt 重新使用TextField组件响应车轮事件,并进行信号处理
我丰富了一个文本字段(显示一个浮动),这样它就可以通过鼠标滚轮进行更改,同时仍然可以手动编辑 我发现了Qt 重新使用TextField组件响应车轮事件,并进行信号处理,qt,qml,Qt,Qml,我丰富了一个文本字段(显示一个浮动),这样它就可以通过鼠标滚轮进行更改,同时仍然可以手动编辑 我发现了forceActiveFocus和onClicked的怪癖(我希望我能像Qt一样让所有事件沿着小部件堆栈传递),并使用onWheel更改值(如果这不是最好的方法,请告诉我): 我想在多个地方重复使用此组件而不是TextField(无需复制和粘贴),因此我尝试如下方式声明该组件: Component{ id: wheeledFloatTextField property real
forceActiveFocus
和onClicked
的怪癖(我希望我能像Qt一样让所有事件沿着小部件堆栈传递),并使用onWheel
更改值(如果这不是最好的方法,请告诉我):
我想在多个地方重复使用此组件而不是TextField(无需复制和粘贴),因此我尝试如下方式声明该组件:
Component{
id: wheeledFloatTextField
property real initValue: 0.
property real dWheel: 0.5
signal editingFinished(real value);
TextField{
text: parent.initValue.toString();
// re-emit signal to the component
// so that user-defined slot can be defined when re-used
onEditingFinished: parent.editingFinished(parseFloat(text));
// validator: ...
MouseArea{
anchors.fill: parent
propagateComposedEvents: true
onClicked: { parent.forceActiveFocus(); }
onWheel: {
parent.text=parseFloat(parent.text)-parent.parent.dWheel*wheel.angleDelta.y/120;
parent.editingFinished();
}
}
}
}
和重复使用:
Loader{
sourceComponent: wheeledFloatTextField
initValue: cxxObject.floatAttribute;
onEditingFinished: { cxxObject.floatAttribute=value; }
}
然而,我得到(在使用组件的行中):
怎么了?我收集了一些帖子(如和),我可能需要将组件
的内部(好像它是一个单独的.qml
文件,并且没有定义范围)封装在项
或容器
中,但我不确定该怎么做。有什么提示吗
我希望先将定义内联,然后移动到单独的文件。如果在单独的文件中声明了组件,则可以(应该)忽略顶级组件。为了最大限度地重用组件,建议在单独的文件中声明它们。
组件
不能声明任何属性。它基本上是在原型状态下停止对象创建。如果要配置对象以供以后创建,例如延迟初始化(委托),这非常有用。
如果您有一个类型为Component
的属性,并且使用myProp:SomeType{…}
语法,它将自动从该属性创建一个组件
我认为最好的解决方案是将TextField放在一个单独的文件中,并将属性添加到根节点,这样它就可以自定义
文件1(例如“CustomTextField.qml”)
然后,您可以以所有已知的方式重用组件,如在加载程序中:
Loader {
sourceComponent: CustomTextField { // Property type is component, so it automatically creates a Component instead of the full-blown object, until it is loaded.
initValue: 12
dWheel: 42
}
...
}
或不带加载器
CustomTextField {
...
}
当然,您可以将其内联,但即使这样,您也必须将属性添加到组件中的根元素中
Component {
id: componentId // only thing you can set besides one Object in a Component
TextField{
id: componentRoot // You can't reference this id from outside the Component!!!
property real initValue: 0.
property real dWheel: 0.5
signal editingFinished(real value);
text: initValue.toString();
// re-emit signal to the component
// so that user-defined slot can be defined when re-used
onEditingFinished: editingFinished(parseFloat(text));
// validator: ...
MouseArea{
anchors.fill: parent
propagateComposedEvents: true
onClicked: { parent.forceActiveFocus(); }
onWheel: {
parent.text=parseFloat(parent.text)-parent.parent.dWheel*wheel.angleDelta.y/120;
parent.editingFinished();
}
}
}
}
这样做的缺点是,您总是需要一个单独的对象来实例化组件,比如加载程序
,这会增加开销并使对象之间的文件通信复杂化,因为要解决它,您需要使用:loaderId.item.property
,这在查找时可能会很昂贵,您需要确保项目
已定义为e.t.c
Loader {
sourceComponent: CustomTextField { // Property type is component, so it automatically creates a Component instead of the full-blown object, until it is loaded.
initValue: 12
dWheel: 42
}
...
}
CustomTextField {
...
}
Component {
id: componentId // only thing you can set besides one Object in a Component
TextField{
id: componentRoot // You can't reference this id from outside the Component!!!
property real initValue: 0.
property real dWheel: 0.5
signal editingFinished(real value);
text: initValue.toString();
// re-emit signal to the component
// so that user-defined slot can be defined when re-used
onEditingFinished: editingFinished(parseFloat(text));
// validator: ...
MouseArea{
anchors.fill: parent
propagateComposedEvents: true
onClicked: { parent.forceActiveFocus(); }
onWheel: {
parent.text=parseFloat(parent.text)-parent.parent.dWheel*wheel.angleDelta.y/120;
parent.editingFinished();
}
}
}
}