I want to implement the following scenario in QML.
Here is a sample/simplified delegate for ListView
element:
Component {
Item {
id: container
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
container.ListView.view.currentIndex = index
container.forceActiveFocus();
}
onEntered: {
actionList.state = "SHOW";
myItem.state = "HOVER"
}
onExited: {
actionList.state = "HIDE";
myItem.state = "NORMAL"
}
Rectangle {
id: myItem
color: "gray"
anchors.fill: parent
Row {
id: actionList
spacing: 5; anchors.fill: parent
Image {
id: helpAction
source: "" //Some image address
width: 16; height: 16; fillMode: Image.PreserveAspectFit
states: [
State {
name: "NORMAL"
PropertyChanges { target: helpAction; opacity: 0.7 }
},
State {
name: "HOVER"
PropertyChanges { target: helpAction; opacity: 1.0 }
}
]
MouseArea {
hoverEnabled: true
anchors.fill: parent
onEntered: {
parent.state = "HOVER";
}
onExited: {
parent.state = "NORMAL";
}
}
states: [
State {
name: "SHOW"
PropertyChanges { target: actionList; visible: false }
},
State {
name: "HIDE"
PropertyChanges { target: actionList; visible: true }
}
]
}
//Other action buttons...
states: [
// `NORMAL` and `HOVER` states definition here...
]
}
}
}
}
But I have a problem with MouseArea
.
Inner MouseArea
(actionButton) does not work properly for entered
event. When mouse enters on action button, outer MouseArea
fires exited
event.
Is there any mistake in my code? More generally, how can I implement such a scenario in QML?
I was faced by this same problem, and came across the answer in the QtQuick 5.0 documentation for
MouseArea
. The answer to this is actually quite simple.If you want to include child mouse hover events in your parent
MouseArea
, make you childMouseArea
a child of the parentMouseArea
:Since I have a custom
Widget
type that would be used as the parent view, I ended up with thedefault
property being the children of theMouseArea
:Try this:
Mouse exit on both will still cancel hover state. As you move the mouse off the controls it should work correctly without any extra code
Iv'e tried a few things but it does not seem possible to hover over two
MouseArea
simultaneously. ThepreventStealing
andpropagateComposedEvents
seem to only work when you have a click event. But from the innerMouseArea
you can trigger theentered()
signal of the other one. Something like this:The issue is that the
exited()
signal from the containingMouseArea
will be called before calling theentered()
back again. So you might need to "delay" the change of state inexited()
just to make sure you really want to hide your action buttons. Another solution would be to save the current mouse position and hide the buttons ONLY ifexited()
is called with the mouse on one of its border.make states for each state of the elements in the View then you can use things like if statements or case statements to change these properties In Other words, Try not to set your elements up to work on MouseArea but on properties And set the Elements properties to work on the set properties I hope that this helps if not here is example:
EDIT I added the color to be transparent. if there is no mouse what so ever. If I was using a Image I would use opacity then add a bunch of Behaviors also But this is a working
example