I would like to created a nested TableView for some elements of my main TableView.
For example, if Rowtitle == ""Brilliance" , I would like to created a subTableView for this row.
ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
TableView {
TableViewColumn {
role: "title"
title: "Title"
width: 100
//if title==""Brilliance" create a second tableview
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
model: libraryModel
}
Do you have any idea how to do it ?
Thanks a lot !
Related
I'm developing an application. I need to add data to TreeView but I have some problems with TreeView's nested model.
I created a List Model which is
ListModel {
id: fruitModel
ListElement {
name: "Apple"
price: 2.45
}
}
I am able to show this item by the way of
TreeView {
id: mytreeView
anchors.fill: parent
model: fruitModel
TableViewColumn {
title: "Name"
role: "name"
width: 200
}
TableViewColumn {
title: "Price"
role: "price"
width: 200
}
}
However , I need to show nested items like
ListModel {
ListElement {
categoryName: "Fruits"
collapsed: true
subItems: [
ListElement { itemName: "Orange" , itemPrice: 2.40},
ListElement { itemName: "Apple" , itemPrice: 2.40},
ListElement { itemName: "Pear" , itemPrice: 2.40},
ListElement { itemName: "Lemon" , itemPrice: 2.40}
]
}
}
I listed these items in ListView but I need to list these items in TreeView. So, how can I list this nested ListModel in TreeView using QML?
First, you need to correct the roles to match your new nested model/ListElement's scope/roles. And build your model correctly (you using "," for ListElement items .. use ";") as corrected below.
Second , use listmodel function object get(index) to iterate down and lockup the nested model.
THis will work!:
ListModel {
id:fruitModel
ListElement {
categoryName: "Fruits"
collapsed: true
subItems: [
ListElement { itemName: "Orange" ; itemPrice: 2.40},
ListElement { itemName: "Apple" ; itemPrice: 2.40},
ListElement { itemName: "Pear" ; itemPrice: 2.40},
ListElement { itemName: "Orange" ; itemPrice: 2.40}
]
}
ListElement {
categoryName: "Vegetable"
collapsed: true
subItems: [
ListElement { itemName: "Broccoli" ; itemPrice: 4.20},
ListElement { itemName: "Garlic" ; itemPrice: 7.40},
ListElement { itemName: "beens" ; itemPrice: 6.40},
ListElement { itemName: "Eggplant" ; itemPrice: 1.40}
]
}
}
TreeView {
id: mytreeView
anchors.fill: parent
model:fruitModel.get(0).subItems // get nested model this way , or by Javascript!
TableViewColumn {
title: "Name"
role: "itemName" // here
width: 200
}
TableViewColumn {
title: "Price"
role: "itemPrice" // here
width: 200
}
//Component.onCompleted: model= fruitModel.get(0).subItems
}
UpDate:
To display multiple nested elements , you can use section property with ListView and display nested model with TreeView :
ListView {
anchors.fill: parent
model: fruitModel
delegate: nameDelegate
focus: true
highlight: Rectangle {
color: "lightblue"
width: parent.width
}
section {
property: "categoryName"
criteria: ViewSection.FullString
delegate: Rectangle {
color: "#b0dfb0"
width: parent.width
height: childrenRect.height + 4
Text { anchors.left: parent.left
font.pixelSize: 16
font.bold: true
text: section
}
}
}
}
Component {
id: nameDelegate
TreeView {
id: mytreeView
width: parent.width
model:fruitModel.get(index).subItems // get nested model
TableViewColumn {
title: "Name"
role: "itemName" // here
width: 200
}
TableViewColumn {
title: "Price"
role: "itemPrice" // here
width: 200
}
}
}
How can we on a TableView from QtQuick.Controls 2.2 detect a scroll event?
For exemple when i scroll down vertically i want to detect that event with something like onVerticalDown or something similar…
In attachment i provide na exemple of what i'm implementing:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 300
ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
Page {
id: page
anchors.fill: parent
TableView{
id:table
anchors{
top:parent.top
topMargin:10
left:parent.left
right:parent.right
bottom:parent.bottom
}
style: TableViewStyle{
backgroundColor : "white"
textColor: "white"
highlightedTextColor: "white"
handle: Rectangle {
implicitWidth: 30
implicitHeight: 30
color: "black"
}
}
model: libraryModel
headerDelegate: Rectangle{
id:recHeader
width:styleData.width+20
height:30
color:"blue"
border.color: "black"
border.width: 1
Text {
anchors.fill:parent
text:styleData.value
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
itemDelegate: Rectangle {
border.color:"black"
border.width: 1
Text
{
text: styleData.value
elide: Text.ElideRight
}
}
Component.onCompleted: {
showcolumn1()
}
TableViewColumn {
id: col1
role: "title"
title: "Title"
}
TableViewColumn {
role: "author"
title: "Authors of this tutorial"
}
}
}
}
When we run it's like this:
Now i scroll down and i want to detect it:
How can this be done?
You can access the scroll position on the flickableItem.contentY property:
TableView {
flickableItem.onContentYChanged: console.log("scrolled:", flickableItem.contentY)
// ...
}
TableView in QML is really wierd in my opinion at least on QtQuick.Controls 1.4
It's happening the following in windows:
on mac:
Why are they so different?? I don't understand. How can i make them the same.
As we can see on windows the scrollBar starts at the top of the table, but on mac it starts below the header.
Below i provide the code for the table:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 300
ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
Page {
id: page
anchors.fill: parent
TableView{
id:table
anchors{
//top:chooseColum.bottom
topMargin:10
left:parent.left
right:parent.right
bottom:parent.bottom
}
model: libraryModel
headerDelegate: Rectangle{
id:recHeader
width:styleData.width+20
height:30
color:"blue"
border.color: "black"
border.width: 1
Text {
anchors.fill:parent
//color:globals.text.textColor
text:styleData.value
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
itemDelegate: Rectangle {
border.color:"black"
border.width: 1
Text
{
text: styleData.value
elide: Text.ElideRight
}
}
TableViewColumn {
id: col1
role: "title"
title: "Title"
}
TableViewColumn {
role: "author"
title: "Authors of this tutorial"
}
}
}
}
for now it's not an option to update QT to 5.12.
Qt Quick Controls 1.x are supposed to provide a native look and feel to your UI. I don't know how macOS displays scroll bars, but if it is different from Windows it will be the case for Qt Quick Controls 1.x.
You have got two solution for this :
Consider switching to Qt Quick Controls 2.x, but they do not handle native L&F.
Customize your scroll bars : https://doc.qt.io/qt-5/qtquick-controls-styles-qmlmodule.html
How can we make the columns ocuppy all of the size of the parent?
Why am i asking this? Because as we can see on a simple example the columns dont fill all of the size of table and this is ugly.
The only thing i dont want to happen to a column is to have it with less width than the contents of its column.
I want the solution to work for many columns.
How can we succesfully do it?
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.1
ApplicationWindow {
id: window
title: "Stack"
visible: true
width: 1400
ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
Page {
id: page
anchors.fill: parent
TableView{
style: TableViewStyle{
handle: Rectangle {
implicitWidth: 15
implicitHeight: 15
color: "#000000"
}
minimumHandleLength: 30
}
anchors.fill:parent
TableViewColumn {
role: "title"
title: "Title"
width: 100
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
model: libraryModel
itemDelegate: Text
{
text: styleData.value
elide: Text.ElideRight
}
}
}
}
Has pointed on an answer something like
width: (table.width / table.columnCount) - 1
can be used but i dont want to happen in small widths for items/text to be cut i want the scroll bar to appear:
Like this ? -1 is just to avoid seeing an annoying scrollbar (probably caused by margins/borders)
TableView{
id: table
anchors.fill:parent
style: TableViewStyle{
handle: Rectangle {
implicitWidth: 15
implicitHeight: 15
color: "#000000"
}
minimumHandleLength: 30
}
TableViewColumn {
role: "title"
title: "Title"
width: (table.width / table.columnCount) - 1
}
TableViewColumn {
role: "author"
title: "Author"
width: (table.width / table.columnCount) - 1
}
model: libraryModel
itemDelegate: Text
{
text: styleData.value
elide: Text.ElideRight
}
}
I want to customize the ScrollBar in a TableView.
I am able to customize the ScrollBar in ListView and GridView but I couldn't do the same with the TableView.
I found that this is because GridView and ListView inherit from the Flickable but TableView inherits from ScrollView. Is there any alternative for this?
TableView {
id:songGrid
TableViewColumn {
role: "title"
title: "Title"
width: 100
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
ScrollBar.horizontal: ScrollBar {
id: scrollBar2
anchors.bottom: songGrid.bottom
// anchors.bottomMargin: 70*downscaleFactor
width: 5
active: true
visible:songGrid.moving?true:false
contentItem: Rectangle {
id:contentItem_rect2
width:100
implicitHeight:4
radius: implicitHeight/2
color: "Red"
}
}
model: libraryModel1
}
ListModel {
id: libraryModel1
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
You can just create a ScrollBar, put it where ever you want. Then you bind the songGrid.flickableItem.contentX/Y to the ScrollBar.position in the correct way. If the TableView can be moved by other means then the ScrollBar you need to use a second Binding to update the position in those cases.
This is a short sketch-up in which I only account for the direction: ScrollBar -> TableView (add it to the code from your Question).
Binding {
target: songGrid.flickableItem
property: "contentY"
value: (songGrid.flickableItem.contentHeight + 16) * vbar.position - (16 * (1 - vbar.position))
}
ScrollBar {
id: vbar
z: 100
orientation: Qt.Vertical
anchors.top: songGrid.top
anchors.left: songGrid.right
anchors.bottom: songGrid.bottom
active: true
contentItem: Rectangle {
id:contentItem_rect2
radius: implicitHeight/2
color: "Red"
width: 10 // This will be overridden by the width of the scrollbar
height: 10 // This will be overridden based on the size of the scrollbar
}
size: (songGrid.height) / (songGrid.flickableItem.contentItem.height)
width: 10
}
You can see those mysterious 16 in the Binding. This is some offset that is needed, probably to account for the horizontal ScrollBar. This might be different for different styles/platforms.
If you have further questions, please ask a new question. If you only need more clarification, place a comment.
You can use Qt Quick Controls Styles QML Types to change the appearance of scrollbar.
TableView has an style attribute inherit from ScrollView. To customize the scrollbar, just override it.
Here is a simple example.
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
TableView {
id: songGrid
TableViewColumn {
role: "title"
title: "Title"
width: 100
}
TableViewColumn {
role: "author"
title: "Author"
width: 200
}
model: libraryModel1
style: TableViewStyle {
handle: Rectangle {
implicitHeight: 17
color: "red"
}
}
ListModel {
id: libraryModel1
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
}
You can also change the background of scorllbar, appearance of increment/decrement button... etc. For more information, please refer to
ScrollViewStyle QML Type(The parent class of TableViewStyle)
BTW, if you want to create a new scrollbar as derM said, you can set horizontalScrollBarPolicy or verticalScrollBarPolicy to
Qt.ScrollBarAlwaysOff to disable default scrollbar.These two property were both from ScrollView