问题
I'm using Qt 5.4.1.
I'm currently setting up some buttons in QML. I want similar state behaviours for some of the buttons - how to do I avoid having large chunks of very similar code repeated through the QML?
Rectangle {
id: songFilterButton
x: 0; width: 80
y: 0; height: 60
Text {
anchors.centerIn: parent
text: "Songs"
}
state: "on"; states: [
State {
name: "on"
PropertyChanges{ target: songFilterButton; color: "steelblue" }
},
State {
name: "on"
PropertyChanges{ target: songFilterButton; color: "white" }
}
]
MouseArea { id: region; anchors.fill: parent; onClicked: songFilterButton.toggle() }
function toggle() {
if(state == "on") { state = "off" } else { state = "on" }
}
}
That would be quite a bit of code to repeat for several buttons, and each time I add to a button functionality (like sending signals to C++ and other behaviours), I would have to do it multiple times...
I've read over the link provided by MrEricSir and created a HKRadioButton.qml with the following code:
import QtQuick 2.0
Rectangle {
property string text: label.text
Text {
id: label
anchors.centerIn: parent
}
state: "on"; states: [
State {
name: "on"
PropertyChanges{ target: songFilterButton; color: "steelblue" }
},
State {
name: "off"
PropertyChanges{ target: songFilterButton; color: "white" }
}
]
MouseArea { anchors.fill: parent; onClicked: parent.toggle() }
function toggle() {
if(state == "on") { state = "off" } else { state = "on" }
}
}
In my main QML file, I have
HKRadioButton {
id: songFilterButton
x: 0; width: 80
y: 0; height: 60
text: "Songs"
}
I get the behaviour (changing state), but not the text...
回答1:
Define your own components. You can create a component "in place" and then right-click on the component's root object -> Refactoring -> Move component into separate file. For example:
Rectangle {
id: button
...
}
After you move that to a Button.qml, you can just use:
Button {
...
}
Use "inline" components:
Component {
id: button
Rectangle {
...
}
}
Then you can use button
with a Loader
or for dynamic instantiation using button.createObject(parentItem)
As the other answer noted, if you want to create properties for your component which refer to some sub-object properties, use an alias property, helps avoid unnecessary bindings.
Rectangle {
property string text
Text {
id: label
anchors.centerIn: parent
text: parent.text // this is what you want
}
...
}
But that would introduce a needless binding, you can use an alias
to directly reference the label's text
from the root component property as folibis suggested.
回答2:
Change
property string text: label.text
to
property alias text: label.text
Now you just assign label
.text
to own property HKRadioButton
.text
but it should be just the opposite action.
来源:https://stackoverflow.com/questions/28909050/how-to-avoid-repetitive-code-in-qml