TableView - How to get hovered row without loosing styleData.selected - qt

I need to highlight the hovered row in a TableView.
By default there is no hovering effect.
I can use a MouseArea inside rowDelegate to achieve this.
But this will disable selection mechanism in TableView.
Means styleData.selected will not work anymore.
Which means I have to program each and every line of code for the selection mechanism including extended selection.
How to solve this issue? I just need a little property such as styleData.hovered like in handle component of ScrollViewStyle
The question is already asked 3 years & 2 months ago. Unanswered unfortunately.
QML how to use mouse hover together with styleData.selected
UPDATE
rowDelegate: Rectangle {
height: 30
property color selectedColor: styleData.hasActiveFocus ? "gray" : "lightgray"
color: styleData.selected ? selectedColor : mouse_area.hovered?"black":backgroundColor
MouseArea{
id:mouse_area
property bool hovered:false
propagateComposedEvents : false
hoverEnabled: true
anchors.fill: parent
onEntered: {
hovered=true
}
onExited: {
hovered=false;
}
}
}

Adding:
MouseArea {
// ...
onPressed: mouse.accepted = false
}
will propagate the mouse signal to the TableView and keep its selection behavior.

Related

Change ListView's current index background color and not override other "states"

My Qt Quick Control 2 app is using Material Dark Theme. I would like to change background color of selected item in ListView. I know that I can do this in item delegate:
SwipeDelegate {
id: delegate
checkable: true
spacing: 0
width: parent.width
background: Rectangle {
color: index===currentIndex ? "red" : "transparent"
}
But with change above I'm losing defaults padding etc and also Material's radial animation on press and hold state is missing too. Is it possible to just change color only of selected item and keep original behavior for other states of item? Seems that I must reimplement missing things by my self
Maybe you should consider to implement highlight. The following worked for me:
ListView {
// ... Your stuff ...
highlight: Rectangle { color: "lightsteelblue"; }
focus: true
}

QML - How to drag a ToolButton?

The QT documentation has this tutorial.
I initially followed it exactly, and it works. I then made two modifications:
I replaced the ListView with a GridView (that works without #2).
I attempted to add a ToolButton to my delegate inside the Rectangle "content" like so:
Rectangle {
id: content
ToolButton {
id: toolButton
icon.color = "transparent"
icon.source = "image://Loader/iconName"
}
Drag.active: dragArea.held
Drag.source: dragArea
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
}
This does not work, the ToolButton appears to be processing the mouse movements and not propagating the messages (I can click the button, but I can not drag it)? This is actually somewhat expected to be honest.
So that said, does anyone have a good way of dragging ToolButtons around? Or is it just accepted that you can't do that? I have tried various combinations of Rectangles and MouseAreas but I can't seem to do one without breaking the other (ie either the drag fails or the button fails).
You can move the MouseArea as a child of the ToolButton to manage the drag with pressAndHold, and propagate the click to keep the button behavior:
Rectangle {
id: content
ToolButton {
id: toolButton
// bind the visual state of the button to the MouseArea
background: Rectangle {
color: marea.pressed
? Qt.darker("blue")
: marea.containsMouse
? Qt.lighter("blue")
: "blue" // use your desired colors
}
MouseArea {
id: marea
property bool held: false
drag.target: held ? content : undefined
drag.axis: Drag.YAxis
anchors.fill: parent
hoverEnabled: true
onPressAndHold: held = true
onReleased: held = false
onClicked: toolButton.clicked() // propagate clicked event to the ToolButton
}
}
// ...
}

How make QML ListView not flickable?

I was wondering if there's any way for ListView to behave like a desktop control and not react with scrolling to mouse dragging?
I know about the interactive property, but I still want the ListView to react to clicks, mouse wheel, arrow keys, and have a ScrollBar.
For starters, setting interactive to false will pretty much immobilize the view.
There is a keyNavigationEnabled property which doesn't seem to work at this moment(this critical bug).
So will need to do a little extra work to get it to work as you want:
MouseArea {
anchors.fill: ll
onWheel: ll.flick(0, wheel.angleDelta.y * 5)
}
ListView {
id: ll
model: 50
width: 50
height: 200
spacing: 5
focus: true
interactive: false
boundsBehavior: Flickable.StopAtBounds
Keys.onPressed: {
if (event.key === Qt.Key_Up) flick(0, 500)
else if (event.key === Qt.Key_Down) flick(0, -500)
}
delegate: Rectangle {
width: 50
height: 50
color: "red"
MouseArea {
anchors.fill: parent
onClicked: console.log("clicked")
}
}
}
Interactivity is disabled, key navigation is implemented manually, and a background MouseArea is used to capture wheel events. Note that you don't have to do anything special to enable clicking on items for a non-interactive view, it works regardless of the view is interactive or not.

How can I get the drop effect of a DragArea to animate towards the DropArea that received it?

Hope this makes some sense as a question. In my app, I have a DragArea defined which I use to start dragging things over top of various Rectangles that each contain a DropArea. Everything is working fine in my code except for a cosmetic effect that I would like to change.
In QML, when you start dragging from a DragArea and eventually drop, the animation effect is such that the thing you're dragging animates (while fading out) back to the spot from which you started dragging. This happens even when you drop over a DropArea that successfully captures the drop.
What I would like to do is have the drop effect animate towards the DropArea that received the drop - so that it appears I am dragging-and-dropping things into the Rectangle. Is there any way to do this?
I'm guessing that this in some way involves the .source and .target properties of these areas, but no luck so far in having any effect on where the drop animation goes.
By default, QML will give you no cosmetic behavior for drag and drop whatsoever. The drag target will begin at the drag start location, and will end wherever it is dropped, regardless of whether the drag is accepted or not.
Thus I assume the behavior you describe is implemented in your user code, which you have not disclosed. Regardless, what you want to do is quite easy, it involves tracking the position the drag originates at and it ends at, so you can use the two coordinates to animate the position.
In the following example the red rectangle can be dragged, and if dropped outside of a drop area it will animate from its current to its initial position, whereas if dropped in the yellow rectangle, it will animate from its initial to its drop position.
Window {
width: 600
height: 600
visible: true
Rectangle {
width: 200
height: 200
color: "yellow"
DropArea {
anchors.fill: parent
onEntered: drag.source.accepted = true
onExited: drag.source.accepted = false
}
}
Rectangle {
id: rect
width: 50
height: 50
color: "red"
x: parent.width * 0.5
y: parent.height * 0.5
Drag.active: mouseArea.drag.active
property point begin
property point end
property bool accepted : false
MouseArea {
id: mouseArea
anchors.fill: parent
drag.target: parent
onPressed: rect.begin = Qt.point(rect.x, rect.y)
onReleased: {
rect.end = Qt.point(rect.x, rect.y)
aX.from = rect.accepted ? rect.begin.x : rect.end.x
aX.to = rect.accepted ? rect.end.x : rect.begin.x
aY.from = rect.accepted ? rect.begin.y : rect.end.y
aY.to = rect.accepted ? rect.end.y : rect.begin.y
anim.start()
}
ParallelAnimation {
id: anim
NumberAnimation { id: aX; target: rect; property: "x"; duration: 200 }
NumberAnimation { id: aY; target: rect; property: "y"; duration: 200 }
}
}
}
}

QML MouseArea onEntered hoverEnabled does not work

a pretty simple scenario, actually:
Text {
text: "Hover me!"
font.family: "Arial"
font.pointSize: 16
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
parent.color = "#ffffff"
}
onExited: {
parent.color = "#000000"
}
}
}
As you can see, all i want is that the text color changes when i hover it. However, it works only when i'm holding down my left mouse button. Since i'm pretty new to Qt, i've no idea where the problem could be. I googled all day to find an answer, but everything leads me to the "set hoverEnabled: true" solution, which i'm already using.
I'm working on windows with Qt 2.4.1 including VPlay (doesn't think that VPlay matters here)
From your snippet, it looks like you're not assigning the Text element a size (either explicitly or via anchoring), so it has a width/height of (0,0), which means it will never contain the mouse cursor. Note that in QtQuick, the size of items is not defined by their contents or where they paint (an item can paint anywhere outside of its (position, size) rectangle). An item without explicit width/height attributes or anchoring will have a size of (0,0), no matter how it appears on screen.
In the following example, the mouse area has a size of 360, 360 inherited from its parent rectangle (via anchors.fill: parent):
import QtQuick 2.0
Rectangle {
width: 360
height: 360
color: "black"
Text {
anchors.centerIn: parent
text: qsTr("Hello World")
color: mouseArea.containsMouse ? "red" : "white"
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
}
}
}
I preferred the declarative approach using a property binding with containsMouse here, but onEntered/onExited would work as well.

Resources