QML: ListView delegate: items vs. MouseArea - qml

I have the following code:
ListView {
delegate: MyDelegate {
MouseArea {
anchors.fill: parent
/*some other stuff*/
}
}
}
The problem is that MyDelegate contains checkboxes and MouseArea "steals" mouse events from them. They do not react on mouse events at all, i.e. do not work as expected.
I know about propagateComposedEvents property of MouseArea...but I'll have to implement all of its mouse events (clicked, pressed, released,...) and check whether the mouse cursor is in the checkbox or not to set mouse.accepted property accordingly.
This is how I understood all of these currently. Is there any easier way, i.e. a way to be able to process all of the mouse events for areas that does not handle mouse events explicitly? For instance static text, progress bars, etc.

You can apply negative values to the z property of the MouseArea.
From the documentation:
Items with a higher stacking value are drawn on top of siblings with a lower stacking order. Items with the same stacking value are drawn bottom up in the order they appear. Items with a negative stacking value are drawn under their parent's content.

Related

How to use "Layout.alignment" instead of "anchors.right: someItemID.right"

I have this statement inside my QML item:
Rectangle {
// ...
anchors.right: someItemID.right
// ...
}
I'm receiving this warning for my Rectangle item:
QML Rectangle: Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead.
How can I use Layout.alignment to resolve the above warning? How can I pass another item ID to Layout.alignment? Is it possibe?
A layout manages the positions and sizes of all of its child items. Using anchors inside child items is not allowed as it could override these rules. You can only influence those properties provided by the layout in the Layout object attached to its children, which is hinted at in the warning message. Layout.alignment controls how the item is aligned within the cell created for it by the layout. You can therefore align an item to the edges of its adjacent cells, but you can't directly anchor to their items by ID.
If you need more precise control, you should position the items outside the layout using position and/or anchor properties.

MouseArea in a Disabled QML element

I have a widget that is widely used in my QML Application, it's enabled property has been used in most of the places to change it's view and disable it's actions. Let's say it is something like this
Item {
MouseArea {
anchors.fill: parent
onClicked: doSomething();
}
}
Now the problem is that we need to show a message when the button is disabled, but MouseArea will also be disabled when the parent is disabled. Is there any workaround for this to force the child to remain enabled?
Actually, the mouse area enabled property works differently from typical Items. It's really not disabled, but seems that way because the parent item is not enabled and thus cannot accept certain mouse events. To solve your problem just make the MouseArea a sibling.

CreateJS hit only visible elements

I have two shapes in my canvas using CreateJS. In each shape I included a hit area with the own shape with a mouseover listener. Two shapes are one above the other. When I click into the shape, I received the two callbacks. It's possible to get only the callback to the visible shapes?
enter image description here
Similar to the DOM, the way mouse interaction works is to bubble up the display list, which excludes elements that are not part of the hierarchy chain of the event target.
This means siblings, or elements of other display lists that are underneath will not receive event handlers (which is what you described), and you will not receive mouse events for elements that are not the target of the mouse event.
However, you can wire up your own interaction fairly easily using getObjectsUnderPoint, which tells you what is under the mouse.
stage.on("click", handleClick);
function handleClick(event) {
var list = stage.getObjectsUnderPoint(event.localX, event.localY);
for (var i=0, l=list.length; i<l; i++) {
console.log(list[i]);
}
}
Here is a quick sample: http://jsfiddle.net/y8jhb26x/
Note that you can add the mouse event to any container you want to constrain what objects will trigger this check (I just used stage), but when you call getObjectsUnderPoint, it will return anything under the mouse. If you want to only check items in that container, you can use the contains method to filter out unwanted children:
for (var i=0, l=list.length; i<l; i++) {
if (someContainer.contains(list[i])) {
console.log(list[i]);
}
}
You can also use arguments on getObjectsUnderPoint to filter out items with mouse handlers, or respect the mouseChildren/mouseEnabled property, which is how actual mouse interaction works.
getObjectsUnderPoint method
mouse interaction code
Hope that helps!

How to show current selection QML TreeView?

I can show current selection QML ListView but similar thing doesn't work in TreeView.
Part of the problem is for TreeView it doesn't recognize index which is passed to delegate in case of ListView. I tried styleData.indexbut that doesn't work either.
rowDelegate: Item {
id: row_delegate
height: 40
Rectangle {
id: rectid
anchors.fill: parent
MouseArea {
id: mouse_area
anchors.fill: parent
onClicked: {
console.log("Row clicked " + rectid.styleData.index)
}
}
}
}
The output is:
qml: Row clicked undefined
As stated by the documentation, you have a set of properties within the namespace styleData that can be used for almost the same purposes from within a delegate.
As an example, you can set the text property of a label that is part of your delegate as it follows:
text: styleData.value
Where styleData.value is (documentation excerpt):
the value or text for this item
Similarly, you have:
styleData.pressed - true when the item is pressed
styleData.index - the QModelIndex of the current item in the model
styleData.hasChildren - true if the model index of the current item has or can have children
And so on... Please, refer to the documentation for the full list.
Be aware also of the note at the end of the documentation:
Note: For performance reasons, created delegates can be recycled across multiple table rows. This implies that when you make use of implicit properties such as styleData.row or model, these values can change after the delegate has been constructed. This means that you should not assume that content is fixed whenComponent.onCompleted is called, but instead rely on bindings to such properties.

Zoom Flickable's content on wheel event

By default, Flickable scrolls on mouse wheel event: horizontally if Shift modifier is pressed, and vertically if no modifier is active. I'd like to override this behaviour to make it zoom in/out.
I tried to use MouseArea as a child of Flickable. Defining desired behaviour inside onWheel handler I get what I want, but it breaks flicking feature. Motion of two touch points is recognised as a wheel event on my Mac, what prevents Flickable to steel this event (MouseArea.preventSteeling is false by default). So I get somewhat mixed zooming feature that respects velocity/acceleration behaviour of Flickable.
Add an onWheel handler underneath your MouseArea:
MouseArea
{
onWheel: {
if (wheel.modifiers & Qt.ControlModifier){
if (wheel.angleDelta.y > 0)
{
zoomin()
}
else
{
zoomout()
}
}
else{
wheel.accepted=false
}
}
}