How to detect scroll event on a TableView in qml? - qt

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)
// ...
}

Related

How to make a table scrollbar look the same in both windows and mac

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 to have columns of TableView ocupy all of the parent

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
}
}

How to make a cell editable in qt tableview

I try to make a cell editable using a tableview in qt. I have found a few examples and came up with the following:
TableView {
id: tableView
objectName: "tableView"
horizontalScrollBarPolicy: -1
selectionMode: SelectionMode.SingleSelection
Layout.minimumWidth: 300
Layout.fillHeight: true
Layout.fillWidth: true
model: trackableInfoModel
itemDelegate: Rectangle {
Text {
anchors.verticalCenter: parent.verticalCenter
text: styleData.value
}
MouseArea {
id: cellMouseArea
anchors.fill: parent
onClicked: {
if(styleData.column === 2){
//do something
}
}
}
}
From what I found it looks like I need an itemDelegate to paint each cell. Then I add a MouseArea to the cell and check which cell was selected. In my case I only need to react on the cells in column 2.
The thing is when I use the code shown above I get the error that:
JavaScipt blocks are not supported in a QT Quick UI form. (M223)
Because of that I tried to register a property alias for cellMouseArea like this:
property alias cellMouseArea : cellMouseArea
However that leads to this error:
qrc:/EditPageForm.ui.qml:24 Invalid alias reference. Unable to find id "cellMouseArea"
Overlay cell with TextInput on click.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TableView {
id: tableView
objectName: "tableView"
horizontalScrollBarPolicy: -1
selectionMode: SelectionMode.SingleSelection
anchors.fill: parent
TableViewColumn {
id: titleColumn
title: "Title"
role: "title"
movable: false
resizable: false
width: tableView.viewport.width - authorColumn.width
}
TableViewColumn {
id: authorColumn
title: "Author"
role: "author"
movable: false
resizable: false
width: tableView.viewport.width / 3
}
model: ListModel {
id: libraryModel
ListElement {
title: "A Masterpiece"
author: "Gabriel"
}
ListElement {
title: "Brilliance"
author: "Jens"
}
ListElement {
title: "Outstanding"
author: "Frederik"
}
}
itemDelegate: Rectangle {
Text {
anchors { verticalCenter: parent.verticalCenter; left: parent.left }
color: "black"
text: styleData.value
}
MouseArea {
id: cellMouseArea
anchors.fill: parent
onClicked: {
// Column index are zero based
if(styleData.column === 1){
loader.visible = true
loader.item.forceActiveFocus()
}
}
}
Loader {
id: loader
anchors { verticalCenter: parent.verticalCenter; left: parent.left}
height: parent.height
width: parent.width
visible: false
sourceComponent: visible ? input : undefined
Component {
id: input
TextField {
anchors { fill: parent }
text: ""
onAccepted:{
// DO STUFF
loader.visible = false
}
onActiveFocusChanged: {
if (!activeFocus) {
loader.visible = false
}
}
}
}
}
}
}
}

Nested TableView

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 !

Qt QML ListView visible

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
}
}

Resources