Qt QML ListView visible - qt

I've found the following code in a QML example. I have a question about sections: is there a way to hide all the elements belonging to a section when the user clicks on the section header? For example, is it possible to hide "Ant" and "Flea" when the user clicks the "Tiny" header?
Here is the code:
Rectangle {
id: container
width: 300
height: 360
ListModel {
id: animalsModel
ListElement { name: "Ant"; size: "Tiny" }
ListElement { name: "Flea"; size: "Tiny" }
ListElement { name: "Parrot"; size: "Small" }
ListElement { name: "Guinea pig"; size: "Small" }
ListElement { name: "Rat"; size: "Small" }
ListElement { name: "Butterfly"; size: "Small" }
ListElement { name: "Dog"; size: "Medium" }
ListElement { name: "Cat"; size: "Medium" }
ListElement { name: "Pony"; size: "Medium" }
ListElement { name: "Koala"; size: "Medium" }
ListElement { name: "Horse"; size: "Large" }
ListElement { name: "Tiger"; size: "Large" }
ListElement { name: "Giraffe"; size: "Large" }
ListElement { name: "Elephant"; size: "Huge" }
ListElement { name: "Whale"; size: "Huge" }
}
// The delegate for each section header
Component {
id: sectionHeading
Rectangle {
id: sectionHeadingRectangle
width: container.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20;
}
}
}
Component {
id: section
Rectangle {
width: container.width
height: mainText.height
Text { id: mainText; text: name; font.pixelSize: 18 }
}
}
ListView {
id: view
anchors.fill: parent
// width: parent.width
model: animalsModel
delegate: section
section.property: "size"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
}
}

It is possible to do this by sending a custom signal when a section is clicked and having all delegates connect to this signal and check if the section clicked correspond to theirs, and hide accordingly :
Rectangle {
id: container
width: 300
height: 360
ListModel {
id: animalsModel
ListElement { name: "Ant"; size: "Tiny" }
ListElement { name: "Flea"; size: "Tiny" }
ListElement { name: "Parrot"; size: "Small" }
ListElement { name: "Guinea pig"; size: "Small" }
ListElement { name: "Rat"; size: "Small" }
ListElement { name: "Butterfly"; size: "Small" }
ListElement { name: "Dog"; size: "Medium" }
ListElement { name: "Cat"; size: "Medium" }
ListElement { name: "Pony"; size: "Medium" }
ListElement { name: "Koala"; size: "Medium" }
ListElement { name: "Horse"; size: "Large" }
ListElement { name: "Tiger"; size: "Large" }
ListElement { name: "Giraffe"; size: "Large" }
ListElement { name: "Elephant"; size: "Huge" }
ListElement { name: "Whale"; size: "Huge" }
}
// The delegate for each section header
Component {
id: sectionHeading
Rectangle {
id: sectionHeadingRectangle
width: container.width
height: childrenRect.height
color: "lightsteelblue"
Text {
text: section
font.bold: true
font.pixelSize: 20;
}
MouseArea {
anchors.fill: parent
onClicked: view.sectionClicked(section)
}
}
}
Component {
id: section
Rectangle {
id: rect
width: container.width
height: shown ? mainText.height : 0
visible: shown
property bool shown: true
Text { id: mainText; text: name; font.pixelSize: 18 }
Connections {
target: rect.ListView.view
onSectionClicked: if (rect.ListView.section === name) shown = !shown;
}
}
}
ListView {
id: view
anchors.fill: parent
// width: parent.width
signal sectionClicked(string name)
model: animalsModel
delegate: section
section.property: "size"
section.criteria: ViewSection.FullString
section.delegate: sectionHeading
}
}

Related

QML Gridview overlapping cells

In QmL GridView when applying different values for cellwidth, the cells are getting overlapped.
My requirement is first column cellwidth should be 150
and the rest of the columns cell width value should be 100.
How can we implement the same?
here i need a cellwidth of 150 for the column headings. how can this be done?
i can't use the simple grid as i need the highlight and model property for this application.
import QtQuick 2.12
import QtQuick.Window 2.12
Window
{
id: parent_win
visible: true
width: 800
height: 400
property int cur_row: 0
property int cur_col: 0
property int col_count: 0
property int row_count: 0
Rectangle {
id: modelrect
anchors.left: row_header.right
width: 600; height: 400
color: "white"
border.color: "red"
ListModel
{
id: appModel
ListElement { name: "Heading"; 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: "Heading"; 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: "Heading"; 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: "Heading"; 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" }
}
GridView {
id : test
anchors.fill: parent
cellWidth: 100
cellHeight: 100
focus: true
model: appModel
highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" }
delegate: Item {
width: test.cellWidth
height: test.cellHeight
Image {
id: myIcon
y: 20; anchors.horizontalCenter: parent.horizontalCenter
//source: icon
}
Text {
anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }
text: name
color: (name === "Heading") ? "blue" : "black"
}
MouseArea {
anchors.fill: parent
onClicked: parent.GridView.view.currentIndex = index
}
}
}
}
}
output of the current code
GridView is designed so that all items are the same size. Instead you should use Grid but as you point out the lack of highlighting and model functionality but that you can achieve using a Repeater and a rectangle as I show below:
import QtQuick 2.12
import QtQuick.Window 2.12
Window
{
id: parent_win
visible: true
width: 800
height: 400
ListModel
{
id: appModel
ListElement { name: "Heading"; 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: "Heading"; 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: "Heading"; 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: "Heading"; 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" }
}
Rectangle {
id: modelrect
anchors.fill: grid
width: 650; height: 400
color: "white"
border.color: "red"
}
Grid{
id : grid
property int currentIndex: 0
columns: 6
focus: true
Repeater{
id: repeater
model: appModel
Rectangle{
width: col == 0 ? 150 : 100
height: 100
property int row: index / grid.columns
property int col: index % grid.columns
focus: index == grid.currentIndex
color: focus ? "lightsteelblue": "transparent"
Keys.onPressed: {
var tmp_index = grid.currentIndex
if (event.key === Qt.Key_Down) {
tmp_index += grid.columns
}
else if (event.key === Qt.Key_Up) {
tmp_index -= grid.columns
}
else if (event.key === Qt.Key_Left) {
tmp_index -= 1
}
else if (event.key === Qt.Key_Right) {
tmp_index += 1
}
grid.currentIndex = Math.min(repeater.count - 1, Math.max(0, tmp_index))
}
Image {
id: myIcon
y: 20; anchors.horizontalCenter: parent.horizontalCenter
//source: icon
}
Text {
anchors { top: myIcon.bottom; horizontalCenter: parent.horizontalCenter }
text: name
color: (name === "Heading") ? "blue" : "black"
}
MouseArea {
anchors.fill: parent
onClicked: grid.currentIndex = index
}
}
}
}
}

Disable draging of the view by pressing and holding a mouse button while moving the cursor

I want to disable the dragging of my List view using pressing and holding a mouse button while moving the cursor. I am trying to implement some other feature such as multiple selection using this command. I would only like the scrolling to be enabled. The interactive property of the flickable totally disables the movement of the view. Is there some workaround for this?
I guess there are some ways to achieve what you need, but the following solution works.
The idea is to have a MouseArea and set the interactive property to false when the signals onPressed and onClicked are emitted. interactive should be set to true again in the onReleased handler.
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ListModel {
id: listModel
ListElement {
name: "ttt"
number: "111"
}
ListElement {
name: "rrr"
number: "222"
}
ListElement {
name: "sss"
number: "333"
}
ListElement {
name: "xxx"
number: "444"
}
ListElement {
name: "yyy"
number: "555"
}
ListElement {
name: "zzz"
number: "666"
}
ListElement {
name: "aaa"
number: "777"
}
ListElement {
name: "bbb"
number: "888"
}
ListElement {
name: "ccc"
number: "999"
}
ListElement {
name: "ddd"
number: "011"
}
ListElement {
name: "eee"
number: "022"
}
ListElement {
name: "fff"
number: "033"
}
}
ListView {
id: myList
width: 180; height: 100
clip: true
Component {
id: contactsDelegate
Rectangle {
id: wrapper
width: 180
height: contactInfo.height
color: "lightblue"
Text {
id: contactInfo
text: name + ": " + number
color: "black"
}
MouseArea {
anchors.fill: parent
onPressed: {
myList.interactive = false
console.debug("onPressed")
}
onClicked: {
myList.interactive = false
console.debug("onClicked")
}
onReleased: {
myList.interactive = true
console.debug("onReleased")
}
}
}
}
model: listModel
delegate: contactsDelegate
focus: true
}
}

QML Nested List view with Highlight

I need to create nested list view and as shown below, and highlight the main list and sub-list with different color
I have tried with ListView highlight but there are issue like the highlight showing for child as well as parent as shown
below image.
I am using the code from here with some minor modification.
Here is the full code
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: loginWindow
//visibility: "Maximized"
visible: true
width: 720
height: 720
Item {
width: 200
height: 720
ListView {
id: list
anchors.fill: parent
model: nestedModel
delegate: categoryDelegate
highlight: Rectangle {
color: "#FF00AAFF" //"#FF59ACFF";
radius: 2
}
}
ListModel {
id: nestedModel
ListElement {
categoryName: "Veggies"
collapsed: true
// A ListElement can't contain child elements, but it can contain
// a list of elements. A list of ListElements can be used as a model
// just like any other model type.
subItems: [
ListElement {
itemName: "Tomato"
},
ListElement {
itemName: "Cucumber"
},
ListElement {
itemName: "Onion"
},
ListElement {
itemName: "Brains"
}
]
}
ListElement {
categoryName: "Fruits"
collapsed: true
subItems: [
ListElement {
itemName: "Orange"
},
ListElement {
itemName: "Apple"
},
ListElement {
itemName: "Pear"
},
ListElement {
itemName: "Lemon"
}
]
}
ListElement {
categoryName: "Cars"
collapsed: true
subItems: [
ListElement {
itemName: "Nissan"
},
ListElement {
itemName: "Toyota"
},
ListElement {
itemName: "Chevy"
},
ListElement {
itemName: "Audi"
}
]
}
}
Component {
id: categoryDelegate
Column {
width: 200
Rectangle {
id: categoryItem
border.color: "black"
border.width: 5
color: "#33FF5225"
height: 50
width: 200
Text {
anchors.verticalCenter: parent.verticalCenter
x: 15
font.pixelSize: 24
text: categoryName
}
Rectangle {
color: "red"
width: 30
height: 30
anchors.right: parent.right
anchors.rightMargin: 15
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
// Toggle the 'collapsed' property
onClicked: {
list.currentIndex = index
nestedModel.setProperty(index, "collapsed",
!collapsed)
}
}
}
}
Loader {
id: subItemLoader
// This is a workaround for a bug/feature in the Loader element. If sourceComponent is set to null
// the Loader element retains the same height it had when sourceComponent was set. Setting visible
// to false makes the parent Column treat it as if it's height was 0.
visible: !collapsed
property variant subItemModel: subItems
sourceComponent: collapsed ? null : subItemColumnDelegate
onStatusChanged: if (status == Loader.Ready) item.model = subItemModel
}
}
}
Component {
id: subItemColumnDelegate
Column {
property alias model: subItemRepeater.model
width: 200
Repeater {
id: subItemRepeater
delegate: Rectangle {
x: 10
color: "#33FF5225"
height: 40
width: 190
border.color: "black"
border.width: 2
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
font.pixelSize: 18
text: itemName
}
}
}
}
}
}
}
How can I overcome this issue. Basically I need to highlight Parent and child Item with different color.
Edit:
I can highlight parent list using the code
color:categoryDelegate.ListView.isCurrentItem ? "#FF00AAFF" : "#CCBBBBBB"
but coud'nt a find similar way to change the color of child list (sub list) on click.
Change the color property of the delegate in subItemRepeater to your choice.
Example
Component {
id: subItemColumnDelegate
Column {
...
Repeater {
id: subItemRepeater
delegate: Rectangle {
...
color: "purple"
...
}
}
}
}
Similarly change the color property categoryItem in the categoryDelegate.
Example
Component {
id: categoryDelegate
Column {
...
Rectangle {
id: categoryItem
...
color: "blue"
...
}
}
}
EDIT:
In that case the the overall concept is wrong. In the comment of the original code the author has written A ListElement can't contain child elements, but it can contain a list of elements. So we can't highlight the child item. But the following approach will give good result to you.
import QtQuick 2.0
Rectangle {
width: 360
height: 360
ListModel {
id: model1
ListElement {
name: "name"
}
ListElement {
name: "name"
}
ListElement {
name: "name"
}
}
ListModel {
id: model2
ListElement {
name: "inside"
}
ListElement {
name: "inside"
}
ListElement {
name: "inside"
}
}
ListView {
id: outer
model: model1
delegate: listdelegate
anchors.fill: parent
}
Component {
id: listdelegate
Item {
width: 100
height: col.childrenRect.height
Column {
id: col
anchors.left: parent.left
anchors.right: parent.right
Text {
id: t1
text: name
}
ListView {
id: insidelist
model: model2
property int collapseHeightFlag: childrenRect.height
delegate: Component {
id: delegate2
Item {
width: 100
height: col2.childrenRect.height
Column {
id: col2
anchors.left: parent.left
anchors.right: parent.right
Text {
id: name1
text: name
}
}
MouseArea {
anchors.fill: parent
onClicked: {
insidelist.currentIndex = index;
}
}
}
}
contentHeight: contentItem.childrenRect.height
height: 0
anchors.left: parent.left
anchors.right: parent.right
clip: true
highlight: Rectangle {
color: "pink"
radius: 2
}
focus: true
}
}
Rectangle {
color: "red"
width: 10
height: 10
anchors.right: parent.right
anchors.rightMargin: 5
anchors.top: parent.top
anchors.topMargin: 5
MouseArea {
anchors.fill: parent
onClicked: {
if(insidelist.height === insidelist.collapseHeightFlag) {
insidelist.height = 0;
}
else
insidelist.height = insidelist.collapseHeightFlag;
}
}
}
}
}
}

Is there a IconMode for a listview in qml?

can someone say me how to set up a icon mode for my listViewe in qml?
like this:
I know that this mode is available in the c++ version of the listview (setListMode)but in qml?
Greetings
I don't think there is a default component for this in QML but you can easily do one yourself using the Gridview Component and creating the delegate yourself.
ListModel {
id: modelIcons
ListElement { iconSource: "icon1.jpg"; iconText: "Train1" }
ListElement { iconSource: "icon2.jpg"; iconText: "Train2" }
ListElement { iconSource: "icon3.jpg"; iconText: "Train3" }
ListElement { iconSource: "icon4.jpg"; iconText: "Train4" }
ListElement { iconSource: "icon5.jpg"; iconText: "Train5" }
ListElement { iconSource: "icon6.jpg"; iconText: "Train6" }
ListElement { iconSource: "icon7.jpg"; iconText: "Train7" }
}
Component {
id: delegateListElement
Item {
width: 80
height: width
Column {
Image {
height: 50
width: 50
source: iconSource
}
Text {
text: iconText
}
}
}
}
GridView {
anchors.fill: parent
model: modelIcons
delegate: delegateListElement
focus: true
}

ListView issue in QML

I'm trying to develop an application which has multi-layered navigation in drop-downs.
Below is the snapshot of the requirement. On clicking QSR only the subitems of QSR should pop out with proper alignment.
But with my implementation, I'm getting following result. The pop out window is not aligned, but extending itself to the list.
Below is the my code snippet
import QtQuick 1.1
Item {
width: 500
height: 300
ListView {
anchors.fill: parent
model: nestedModel
delegate: categoryDelegate
}
ListModel {
id: nestedModel
ListElement {
categoryName: "QSR"
collapsed: true
subItems: [
ListElement { itemName: "KFC" },
ListElement { itemName: "Mc Donalds" },
ListElement { itemName: "Pizza Hut" },
ListElement { itemName: "Brain's" }
]
}
ListElement {
categoryName: "Drinks"
collapsed: true
subItems: [
ListElement { itemName: "Pepsi" },
ListElement { itemName: "Coke" },
ListElement { itemName: "7up" },
ListElement { itemName: "Bacardi" }
]
}
}
Component {
id: categoryDelegate
Column {
width: 200
Rectangle {
id: categoryItem
border.color: "black"
border.width: 5
color: "white"
height: 50
width: 200
anchors.left: parent.right
Text {
anchors.right: parent.right
x: 15
font.pixelSize: 24
text: categoryName
}
MouseArea {
anchors.fill: parent
onClicked: nestedModel.setProperty(index, "collapsed", !collapsed)
}
}
Loader {
id: subItemLoader
visible: !collapsed
property variant subItemModel : subItems
sourceComponent: collapsed ? null : subItemColumnDelegate
onStatusChanged: if (status == Loader.Ready) item.model = subItemModel
}
}
}
Component {
id: subItemColumnDelegate
Column {
property alias model : subItemRepeater.model
width: 200
Repeater {
id: subItemRepeater
delegate: Rectangle {
color: "#cccccc"
height: 40
width: 200
border.color: "black"
border.width: 2
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
font.pixelSize: 18
text: itemName
}
}
}
}
}
}
Any help to achieve original requirement will be appreciable.
Have a close look at the delegate for your main list view: It's Column (put items on top of each over) of the main menu item and Loader for the popup menu. Obviously as soon as you load a popup menu it's displayed under its corresponding menu item in the list.
To get the behavior you intended you have to move the Loader for the popup menu out of the ListView:
import QtQuick 1.1
Item {
width: 400
height: 300
Row {
anchors.fill: parent
Loader {
id: subItemLoader
width: 200
height: parent.height
property variant subItemModel: null
sourceComponent: subItemModel == null? null: subItemColumnDelegate
function setModel() {
if (status == Loader.Ready) item.model = subItemModel
}
onStatusChanged: setModel()
onSubItemModelChanged: setModel()
}
ListView {
width: 200
height: parent.height
model: nestedModel
delegate: categoryDelegate
}
}
ListModel {
id: nestedModel
ListElement {
categoryName: "QSR"
subItems: [
ListElement { itemName: "KFC" },
ListElement { itemName: "Mc Donalds" },
ListElement { itemName: "Pizza Hut" },
ListElement { itemName: "Brain's" }
]
}
ListElement {
categoryName: "Drinks"
subItems: [
ListElement { itemName: "Pepsi" },
ListElement { itemName: "Coke" },
ListElement { itemName: "7up" },
ListElement { itemName: "Bacardi" }
]
}
}
Component {
id: categoryDelegate
Rectangle {
id: categoryItem
border.color: "black"
border.width: 5
color: "white"
height: 50
width: 200
Text {
anchors.centerIn: parent
x: 15
font.pixelSize: 24
text: categoryName
}
MouseArea {
anchors.fill: parent
onClicked: {
if (subItemLoader.subItemModel != subItems)
subItemLoader.subItemModel = subItems
else
subItemLoader.subItemModel = null
}
}
}
}
Component {
id: subItemColumnDelegate
Column {
property alias model : subItemRepeater.model
width: 200
height: 500
Repeater {
id: subItemRepeater
delegate: Rectangle {
color: "#cccccc"
height: 40
width: 200
border.color: "black"
border.width: 2
Text {
anchors.verticalCenter: parent.verticalCenter
x: 30
font.pixelSize: 18
text: itemName
}
}
}
}
}
}

Resources