Show Text above Gridview in QML - qt

How can i show text above gridview ?
I tried the following code but on scrolling , gridview elements come over the text and hide it . Even though I specified the width and height of gridview , gridview elements cross there bounds on scrolling . Any help is appreciated . Thanks .
Rectangle {
width: 300; height: 400
color: "gray"
ListModel {
id: appModel
ListElement { name: "Music"; icon: "pics/AudioPlayer_48.png" }
ListElement { name: "Movies"; icon: "pics/VideoPlayer_48.png" }
ListElement { name: "Camera"; icon: "pics/Camera_48.png" }
ListElement { name: "Calendar"; icon: "pics/DateBook_48.png" }
ListElement { name: "Messaging"; icon: "pics/EMail_48.png" }
ListElement { name: "Todo List"; icon: "pics/TodoList_48.png" }
ListElement { name: "Contacts"; icon: "pics/AddressBook_48.png" }
}
Component {
id: appDelegate
Item {
width: 100; height: 100
Image {
id: myIcon
y: 20; anchors.horizontalCenter: parent.horizontalCenter
source: icon
}
Text {
anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }
text: name
}
}
}
Component {
id: appHighlight
Rectangle { width: 80; height: 80; color: "lightsteelblue" }
}
Text
{
id:txt
width: parent.width
height: 100
text: "8791561651"
}
GridView {
anchors.top:txt.bottom
height: 200
width: parent.width
cellWidth: 100; cellHeight: 100
highlight: appHighlight
focus: true
model: appModel
delegate: appDelegate
}
}

There are several way that you can try depending on exactly what you want to achieve:
Set clip property of the Gridview to true. This will prevent the view from going on top of other elements.
Put the Text element after the GridView element. This will make sure that the text is on top of the Gridview. If you do not set the clip however the gridview items will go below the text items.

Related

Is there a way to make unselectable a "list item" in ListView?

I am new to Qt. Wondering if there a possibility to make an item "unselectable" in ListView.
I see there are a lot of other things, e.g: collapsing , expanding, etc.
**
I have not find any simple example for this problem. **
Can you provide some minimalistic examples to make a specific item in the list unselectable?
I have the following minimalistic example. How can I set list item index 2 to be unselectable?
Window {
id: mainWindow
width: 130
height: 240
visible: truetitle: qsTr("Hello")
Rectangle {
id: bg
color: "#ffffff"
anchors.fill: parent
ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jay" }
ListElement { name: "Kate" }
}
Component {
id: nameDelegate
Text {
text: model.name
font.pixelSize: 24
}
}
ListView {
anchors.fill: parent
model: nameModel
delegate: nameDelegate
clip: true
highlight: Rectangle {
anchors { left: parent.left; right: parent.right }
//height: parent.height
color: "lightgrey"
}
}
}
}
I found numerous issues with your code snippet, so I attempted to address them all:
I made use of Page and set Page.background instead of declaring an outer Rectangle. This removes a level of indentation
I refactored NameComponent.qml to reduce the complexity of your main program
I change the delegate from Text to ItemDelegate so that it is clickable, and, it being clickable, I can (1) make the ListView have active focus so that it can receive keyboard events, (2) change the current item in the ListView => I think this achieves your criteria of being able to select a different item
I removed unnecessary anchoring from your highlight - your highlight will default anchor to your selected item
I set the width of your delegate to listView.width - I also made use of the ListView.view attached property so that your delegate and access properties from the ListView
Finally, I added a 20 pixel width vertical ScrollBar
import QtQuick
import QtQuick.Controls
Page {
background: Rectangle { color: "#ffffff" }
ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jay" }
ListElement { name: "Kate" }
}
ListView {
anchors.fill: parent
model: nameModel
delegate: NameDelegate { }
clip: true
highlight: Rectangle {
color: "lightgrey"
}
ScrollBar.vertical: ScrollBar {
width: 20
policy: ScrollBar.AlwaysOn
}
}
}
// NameDelegate.qml
import QtQuick
import QtQuick.Controls
ItemDelegate {
property ListView listView: ListView.view
width: listView.width - 20
text: model.name
font.pixelSize: 24
onClicked: {
listView.forceActiveFocus();
if (listView.currentIndex === index) {
listView.currentIndex = -1;
} else {
listView.currentIndex = index;
}
}
}
You can Try it Online!

How to implement behavior animation on property changes QML

I am trying to change scale property when I click on image, but I would like for it to change slowly. For now I have it instantly when I click on the image (the image gets bigger).
Here are my images:
Here I clicked on the first image and it is slightly bigger than the rest.
Here is my code:
width: 1920
height: 1080
visible: true
title: qsTr("Hello World")
color:'black'
XmlListModel {
id: xmlModel
source: "movies.xml"
query: "/Movies/Movie"
XmlRole { name: "id"; query: "id/string()" }
XmlRole { name: "name"; query: "name/string()" }
XmlRole { name: "year"; query: "year/number()" }
XmlRole { name: "rating"; query: "rating/string()" }
XmlRole { name: "path"; query: "path/string()" }
}
ScrollView{
width:parent.width
height: 400
clip: true
ListView {
id:list
spacing:20
width: parent.width; height: parent.width*0.5
anchors.verticalCenter: parent.verticalCenter
model: xmlModel
clip:true
orientation: ListView.Horizontal
delegate:
Rectangle{ id: rect; width: 300;height: 300; color:'gray'
Image{
id:id
anchors.fill: parent
source:path
fillMode: Image.PreserveAspectFit
scale:focus?1.2:1
MouseArea{
id:area1
width:parent.width
height: parent.height
anchors.fill:parent
Behavior on scale {
PropertyAnimation{ duration: 4000 }
}
onClicked: {
id.scale=1.2
}
//hoverEnabled: true
/*onEntered: {
// hobbit.scale=1.2
id.focus=true
}
onExited: {
// hobbit.scale=1
id.focus=false
}*/
}
}
So, in my code I have Behavior on scale part, but nothing changes. I tried different options and nothing. Any advice? Help would be greatly appreciated.
Move the Behavior object outside the MouseArea object.
Image {
id: img
scale: focus ? 1.2 : 1
Behavior on scale {
PropertyAnimation{ duration: 4000 }
}
MouseArea {
onClicked: {
img.scale = 1.2
}
}
}

I have a ListView where I add and delete ListElements. When I delete a ListElement (row), is there a way to animate the movement of the lower items?

In my ListView, I have an add button which appends a ListElement to the end of the ListView. Each ListElement has a delete button within its row, and when it is clicked, I animate it going away, but I also want to animate any items below when the move up.
ListView {
id: myListView
delegate: myListViewDelegate
model: myListModel
anchors.fill: parent
}
ListModel {
id: myListModel
}
Component {
id: myListViewDelegate
Item {
id: rowContainer
height: 40
width: myListView.width
Text {
id: labelText
text: label
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
}
}
CustomButton {
anchors {
right: parent.right
rightMargin: 8
verticalCenter: parent.verticalCenter
}
width: 32
height: width
buttonRadius: width/2
iconSource: "qrc:/image/Delete.png"
onReleased: deleteRowAnimation.start()
}
ParallelAnimation {
id: deleteRowAnimation
SmoothedAnimation {velocity: 300; target: rowContainer; properties: "x"; to: -rowContainer.width}
onRunningChanged: if(!running) deleteRow(index)
}
}
}
Later in the code..
function deleteRow(index) {
myListModel.remove(index)
}
I am able to animate the row leaving (being deleted), but if there are rows below it, they jump up to fill the spot where the row was deleted. I would like this to be a smooth, animated transition.
Here's a quick example on how it works:
import QtQuick 2.12
import QtQuick.Controls 2.3
ApplicationWindow {
id: window
visible: true
width: 400
height: 400
title: qsTr('Frameless')
flags: Qt.Window | Qt.FramelessWindowHint
ListView {
id: view
anchors.fill: parent
model: ListModel{
ListElement {text: "111111"}
ListElement {text: "222222"}
ListElement {text: "333333"}
ListElement {text: "444444"}
ListElement {text: "555555"}
ListElement {text: "666666"}
ListElement {text: "777777"}
ListElement {text: "888888"}
}
delegate: Text {
id: name
text: qsTr(modelData)
Rectangle {
anchors.fill: parent
color: "red"
opacity: 0.4
}
}
displaced: Transition {
NumberAnimation { property: "y" duration: 200 }
}
}
Shortcut {
sequence: "Esc"
onActivated: view.model.remove(2)
}
}
On Escape the 3rd element element is being removed and that is triggering the rest of the list to move up.
Possibilities of this are endless. Have fun!

Drag and Drop in ListView

I am trying to drag and drop a ListView row and I am having trouble at the drag stage. Below code doesn't drag anything and name column is not aligned properly. I don't want to specify a size for ListView and I want it to get its size from its content Row with id row. It should be able to because text has size coming from its font size and Rectangle has set width. ListView can get wider as needed to show the name part.
import QtQuick 2.11
import QtQuick.Layouts 1.11
ListView {
id: root
height: scrollview.viewport.height
model: listModel
delegate: dragDelegate
Component {
id: dragDelegate
MouseArea {
id: dragArea
anchors { left: parent.left; right: parent.right }
height: content.height
drag.target: pressed ? content : undefined
drag.axis: Drag.XAndYAxis
Rectangle {
id: content
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
height: row.implicitHeight
border.width: 1
border.color: "lightsteelblue"
color: "green"
radius: 2
states: State {
when: dragArea.pressed
ParentChange { target: content; parent: root }
AnchorChanges {
target: content
anchors { horizontalCenter: undefined; verticalCenter: undefined }
}
}
Row {
id: row
Text {
text: name
font.pointSize: 15
}
Rectangle {
height: parent.height
width: 40
color: hexColor
}
}
}
}
}
ListModel {
id: listModel
ListElement {
name: "first-name"
hexColor: "red"
}
ListElement {
name: "second-name"
hexColor: "green"
}
}
}

Qt QML Gridview How to limit items shown?

I'm a QT newbie, i have learned to use grid view by connecting a list model. I want to limit the active viewing images to be just 4 instead of all the items in the list model
Rectangle {
id: Rect1;
width: 1280; height: 720;
ListModel {
id: listAssetModel
ListElement { Movie: "Arrow"; PosterURL: "posters/Arrow.jpg" }
ListElement { Movie: "Avatar"; PosterURL: "posters/Avatar.jpg" }
ListElement { Movie: "Avenge"; PosterURL: "posters/Avenge.jpg" }
ListElement { Movie: "Arrow"; PosterURL: "posters/Arrow.jpg" }
ListElement { Movie: "Avatar"; PosterURL: "posters/Avatar.jpg" }
ListElement { Movie: "Avenge"; PosterURL: "posters/Avenge.jpg" }
ListElement { Movie: "Arrow"; PosterURL: "posters/Arrow.jpg" }
ListElement { Movie: "Avatar"; PosterURL: "posters/Avatar.jpg" }
ListElement { Movie: "Avenge"; PosterURL: "posters/Avenge.jpg" }
}
GridView {
id: gridAssetPreview;
currentIndex: -1 // default - no focus on poster
x: 56; y: 189
width: 1140; height: 300
focus: true
cellWidth: 275; cellHeight: 300 // keeps the poster preview images aligned
highlight: appHighlight
model: listAssetModel
delegate: appDelegate
}
Component {
id: appDelegate
Item {
width: 250; height: 350 // controls the appHighlight size
Image {
id: imgPosterPreview
width: 225; height: 325
source: PosterURL
smooth: true
}
Text {
id: textAssetName
anchors { // draw this below and centre to the image
top: imgPosterPreview.bottom;
horizontalCenter: imgPosterPreview.horizontalCenter
}
text: AssetName
font.pointSize: 16
color:"white"
smooth: true
}
}
}
}
Grid view area is defined as below, but it seems on running it shows multiple rows of images which is not something i expect. I just want to see only 4 images in the whole 1280 x 720 screen.
width: 1140; height: 300
Please help, im stuck with this on my Sunday :-(
Add to your GridView:
flow: GridView.TopToBottom

Resources