How to override some properties of TableView.rowDelegate while keeping others default - qt

I'm using a rowDelegate to implement variable row heights as follows. However, it doesn't use the default background colors for selected/alternate rows. How can I preserve all defaults that I'm not trying to override?
TableView {
id: messagesTable
TableViewColumn {
role: "severity"
title: ""
width: 20
delegate: Image {
anchors.centerIn: parent
fillMode: Image.Pad
source: iconSources[styleData.value.toLowerCase()]
}
}
TableViewColumn {
role: "message"
title: "Message"
width: 300
}
TableViewColumn {
role: "source"
title: "File"
width: 150
}
TableViewColumn {
role: "startLine"
title: "Line"
width: 40
}
TableViewColumn {
role: "startColumn"
title: "Column"
width: 50
}
rowDelegate: Rectangle {
width: childrenRect.width
height: (messagesModel.get(styleData.row).lineCount || 1) * 20
}
model: messagesModel
}

You can't.
The general rule of styling with Qt Quick Controls is: once you override a delegate, you start from scratch. If the styles provided a DefaultTableViewRowDelegate type, for example, you could construct an instance of that and then it would work, but since the default delegates are written inline, you have no way of accessing them.

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 create custom scrollbar for TableView in QML?

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

Can a tableview have columns that take checkbox and image

I am trying to create a component in QML as shown in the attached screenshot
AFAIK, TableView is the component that I should use to create something like this using QML. Looking at the example here it seems that it can support multiple columns and the style is configurable. However, I am not sure how to add the checkbox control and an image element in the columns.
You can start from here:
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
Window {
visible: true
width:1000; height: 500
ListModel {
id: mymodel
ListElement {
title: "my_name.mp4"
check: true
img: "1450465860217s.jpg" //your own img url here
filesize: "1.5GB"
lenght: "20:00"
lastMod: "12/02/2014"
}
ListElement {
title: "my_nam2.mp4"
check: false
img: "1450465860217s.jpg" //your own img url here
filesize: "400MB"
lenght: "8:00"
lastMod: "01/01/2015"
}
ListElement {
title: "my_nam2.mp4"
check: false
img: "1450465860217s.jpg" //your own img url here
filesize: "1.5GB"
lenght: "1:20:00"
lastMod: "12/13/2016"
}
}
TableView {
width: 1000; height: 500
anchors.centerIn: parent
TableViewColumn {
role: "title"
title: "Title"
width: 200
}
TableViewColumn {
role: "filesize"
title: "FileSize"
}
TableViewColumn {
role: "lenght"
title: "Lenght"
}
TableViewColumn {
role: "lastMod"
title: "Last Modified"
}
model: mymodel
rowDelegate: Rectangle{
color: "white"
height: 40
}
itemDelegate: RowLayout {
width: parent == null? 0 : parent.width
Loader{
sourceComponent: styleData.column == 0 ?
things : null
}
Component {
id: things
RowLayout{
height: 30
CheckBox{
id: itemCheckBox
checked: mymodel.get(styleData.row).check
}
Image{
Layout.preferredWidth: 80
Layout.preferredHeight: 40
source: mymodel.get(styleData.row).img
}
}
}
Text {
//anchors.centerIn: parent
text: styleData.value
}
}
}
}
You'll need to code your model in c++ and polish the interface, but its a good starting point.

TreeView - how to use the role as an image source

I have a simple treeview model with defined roles.
Here is a code:
TreeView {
model: theModel
itemDelegate: Rectangle {
color: ( styleData.row % 2 == 0 ) ? "white" : "lightblue"
height: 20
Text {
text: styleData.value === undefined ? "" : styleData.value
}
}
TableViewColumn {
width: 100
role: "name_role"
title: "Map"
}
TableViewColumn {
width: 50
role: "description_role"
title: "Description"
}
Image {
width: 15
source: description_role + ".png"
}
}
In the second column i've got correct description displayed, but when i use this role as an image source i've got mistake "role is undefined".
The question is: How to correctly define role as an image source?
I have found the answer, by reading documentation of the TableViewColumn
The QML treeView should be like this:
TreeView {
model: theModel
itemDelegate: Rectangle {
color: ( styleData.row % 2 == 0 ) ? "white" : "lightblue"
height: 20
Text {
text: styleData.value === undefined ? "" : styleData.value
}
}
TableViewColumn {
width: 100
role: "name_role"
title: "Map"
}
TableViewColumn {
width: 50
role: "description_role"
title: "Description"
}
TableViewColumn {
width: 50
role: "description_role"
title: "Icon"
delegate: Image {
source: styleData.value + ".png"
}
}
}

Make TableViewColumn not resizeable

I've got a TableView with two TableViewColumns and would like to prevent them from being resized.
How can I do this?
TableView {
TableViewColumn {
title: "Name"
width: parent.width - 20
}
TableViewColumn {
width: 18
delegate: CheckBox {
}
}
TableViewColumn {
title: "Name"
width: parent.width - 20
resizable: false
}

Resources