QML TableView Custom delegate: How to make ellipsis for too long text - qt

I want to display a QFileSystemModel in a QML TreeView and need a custom delegate, as I want to add a check box next to a file. This is what I have:
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
TableViewColumn {
id: namecolumn
title: "Name"
role: "fileName"
resizable: true
width: parent.width-sizeWidth-dateWidth-scrollBarWidth
delegate: fileCheckDelegate
}
Component {
id: fileCheckDelegate
Row{CheckBox{}
Text{text: root.getText(model.fileName)}
}
}
However, I have a problem with long filenames going over the column border. The default delegate truncates the text and adds ellipsis to the truncated text. I would like to do the same in my custom delegate, but don't know how this should be done.
As you can see, I tried with a custom getText function, but I don't know which widths and positions to use there for deciding whether a text should be truncated or not
Edit: I found that setting Text.ElideRight on my Text component would do the ellipsis, but I need to set an explicit width. How can I set the width of my Text component right then?

Ok, this does the trick:
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
TableViewColumn {
id: namecolumn
title: "Name"
role: "fileName"
resizable: true
width: parent.width-sizeWidth-dateWidth-scrollBarWidth
delegate: fileCheckDelegate
}
Component {
id: fileCheckDelegate
Row{CheckBox{
id: cbox
}
Text{text: model.fileName
width: namecolumn.width-x-cbox.width
elide: Text.ElideRight
}
}
}

Related

TreeView Delegate with MouseArea: propagate mouse

I have a TreeView with a custom delegate. The delegate uses a ToolTip, which will be shown if the delegates mouseArea is hovered. However, this mouseArea breaks selecting a row in my TreeView. I suppose that a click is not propagated to the TreeView's mouseArea. I tried propagateComposedEvents and mouse.accepted=false but selection does still not work.
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
Component {
id: mycomp
Item {
id: myitm
Row{
id: myrow
CheckBox{
id: cbox
anchors.baseline: ctext.baseline
}
Text{
id: ctext
text: styleData.value
color: styleData.textColor
width: namecolumn.width-cbox.width-myrow.x
elide: Text.ElideRight
}
}
NC.ToolTip {
id: ttip
parent: ctext
text: qsTr(styleData.value)
delay: 500
visible: mouseArea.containsMouse
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: {
mouse.accepted = false
}
}
}
}
Just set the acceptedButtons property of the MouseArea to Qt.NoButton. This property determined the buttons the area will handle. NoButton causes the area to report hover events but it will not handle any clicks.
See the full documentation for the property here:
http://doc.qt.io/qt-5/qml-qtquick-mousearea.html#acceptedButtons-prop

TreeView: Reference Error to model

I have the following TreeView:
TreeView {
id: view
anchors.fill: parent
sortIndicatorVisible: true
model: fileSystemModel
rootIndex: rootPathIndex
selection: sel
selectionMode: 2
TableViewColumn {
id: namecolumn
title: "Name"
role: "fileName"
resizable: true
width: parent.width-sizeWidth-dateWidth-scrollBarWidth
delegate: ItemDelegate {
id: fileCheckDelegate
Row{CheckBox{
id: cbox
y: -4
}
Text{text: model.fileName
width: namecolumn.width-x-cbox.width
elide: Text.ElideRight
}
}
ToolTip {
parent: fileCheckDelegate
visible: hovered
delay: 1000
text: qsTr(model.fileName)
}
}
}
}
Everything is displayed correctly, but in the terminal I get many of the following messages:
qrc:/FileSystem.qml:49: TypeError: Cannot read property 'fileName' of null
qrc:/FileSystem.qml:57: TypeError: Cannot read property 'fileName' of null
The locations are in my delegate, once in Text text: model.fileName and once in ToolTip text: qsTr(model.fileName). As I said, everything is displayed correctly but I am worried that this error might still give me problems. What am I doing wrong?
Edit: A workaround seems to be if I use styleData.value instead of model.fileName. Still, I do not understand why I cannot write model.fileName

Drag and Drop in QML TreeView

In QML i have a TreeView with (properly working) multiselection:
TreeView {
id: treeview
anchors.fill: parent
model: myTestModel
selectionMode: SelectionMode.ExtendedSelection
selection: ItemSelectionModel {
model: treeview.model
}
TableViewColumn {
role: "name_role"
title: "Name"
width: 160
}
TableViewColumn {
role: "type_role"
title: "Type"
width: 75
}
}
I'd like to implement drag & drop to be able to "pull" items out of the treeview into a DropArea.
But when I use the approach I found several times, namely defining an itemDelegate that contains a MouseArea, the selection doesn't work anymore.
TreeView {
id: treeview
anchors.fill: parent
model: myTestModel
// broken due to MouseArea in itemDelegate !
selectionMode: SelectionMode.ExtendedSelection
selection: ItemSelectionModel {
model: treeview.model
}
TableViewColumn {
role: "name_role"
title: "Name"
width: 160
}
TableViewColumn {
role: "type_role"
title: "Type"
width: 75
}
itemDelegate: Item {
Rectangle {
id: rect
anchors.fill: parent
color: styleData.selected ? "blue" : "transparent"
Text {
anchors.verticalCenter: parent.verticalCenter
color: styleData.selected ? "white" : "black"
text: styleData.value
}
MouseArea {
anchors.fill: parent
drag.target: symbolAvatar
onPressed: {
var tmp = mapToItem(container, mouse.x, mouse.y);
symbolAvatar.x = tmp.x;
symbolAvatar.y = tmp.y;
symbolAvatar.dragging = true;
symbolAvatar.text = styleData.value;
}
}
}
}
}
where symbolAvatar is an item that becomes visible when a drag has started.
Any ideas how to implement drag and drop in a QML TreeView without breaking the selection?
Edit: Using the onPressAndHold event handler inside the TreeView would be a solution if I could access the mouse position there, but it doesn't seem to exist :-(

TableView not the correct size with QML

I am trying to create a TableView with QML where I have a checkbox, an image and a text field. The table column definitions are as follows:
// TableViewCheckBoxColumn.qml
TableViewColumn {
title: ""
role: "check"
delegate: CheckBox {
anchors.fill: parent
checked: styleData.value
}
}
//TableViewImageColumn.qml
TableViewColumn {
title: ""
role: "thumbnail"
delegate: Image {
anchors.fill: parent
source: styleData.value
width: 30
height: 30
}
}
Now the data model and the table itself is defined as a QML component as follows:
Item {
ListModel {
id: sourceModel
ListElement {
check: false
thumbnail: "file:///Users/xargon/alignment.png"
length: "10:22"
}
}
// Table view
TableView {
anchors.centerIn: parent
alternatingRowColors: false
TableViewCheckBoxColumn {
id: checkedColumn
}
TableViewImageColumn {
id: thumbColumn
}
TableViewColumn {
id: lengthColumn
role: "length"
title: "Length"
}
model: sourceModel
}
}
Now, this is embedded in a ColumnLayout and a StackView as:
ColumnLayout {
anchors.fill: parent
MyTable {
id: reviewScreen
Layout.fillWidth: true
}
StackView {
id: options
Layout.fillHeight: true
Layout.fillWidth: true
initialItem: reviewScreen
}
}
Now I was expecting the table to fill the entire width of the parent control and I also was expecting the image to be drawn as a 30 x 30 image but what I see is the attached screenshot where the horizontal scrollbar is there to move between controls and the table is small and the image is very distorted as well.
yes, only you need declare heigh and weight of every TableViewColumn, for example:
TableViewColumn { id: lengthColumn; role: "length"; title: "Length"; height: parent.height/8; width:parent.width*0.25}

How to make QML component (widget) adjusts according to data

I have a Widget as QML component in Qt Quick application which is to be used in various screens to display contents.
How can I use this particular QML component to adjust according to the items in it.
If it's a generic Item you can't: you have to manually set the container's size to fit its content.
The only QML components that fits their content are the Row, Column and Grid elements.
coming in way late, but if you want to have an update-able component you can set the model for the component to any list model like:
Component{
id:comp1
model:model1
}
ListModel {
id: model1
ListElement{
name:"a"
}
ListElement{
name: "b"
}
}
Component {
id: fruitDelegate
Row {
spacing: 10
Text { text: name }
}
}
ListView {
id:listView1
anchors.fill: parent
model: fruitModel
delegate: fruitDelegate
contentWidth: Screen.width
}
then you can update the listview at will
TextInput{
id: text_input1
width:parent.width * 0.80
text:"waddup?"
}
Button {
id: button2
anchors.left: text_input1.right
text: qsTr("Send")
onClicked: {
listView1.model.append( {name: text_input1.text, colorCode:"Red" });
/*text_input1.text = ""*/
}
}

Resources