Reputation: 575
I'm trying to make custom component for editable tables in QML, like this:
// BaseTableView.qml
import QtQuick 2.3
import QtQuick.Controls 1.2
Item {
signal addActionPerformed()
signal editActionPerformed(int id)
signal deleteActionPerformed(int id)
property var model
ToolBar {
id: toolBar
anchors.left: parent.left
anchors.right: parent.right
Row {
ToolButton {
id: addButton
iconSource: "qrc:/icons/actions/add.png"
onClicked: addActionPerformed()
}
ToolButton {
id: editButton
enabled: false
iconSource: "qrc:/icons/actions/edit.png"
}
ToolButton {
id: deleteButton
enabled: false
iconSource: "qrc:/icons/actions/delete.png"
}
}
}
TableView {
id: tableView
model: parent.model
anchors.left: parent.left
anchors.right: parent.right
anchors.top: toolBar.bottom
anchors.bottom: parent.bottom
onCurrentRowChanged: {
editButton.enabled = currentRow !== null
deleteButton.enabled = currentRow !== null
}
}
}
and use this component in another file like this:
// Another.qml file
import QtQuick 2.3
import QtQuick.Controls 1.2
import "../common" // Here is BaseTableView.qml
BaseTableView {
TableViewColumn {
role: "id"
title: qsTr("Id")
}
TableViewColumn {
role: "object_expression"
title: qsTr("Expression")
}
}
So, problem is how i can pass table view columns from usage to underlying TableView? I've tried to make property list in BaseTableView and assign a list of objects to this property in Aother.qml? but unsuccessfully.
Upvotes: 2
Views: 1668
Reputation: 24416
Use default properties:
An object definition can have a single default property. A default property is the property to which a value is assigned if an object is declared within another object's definition without declaring it as a value for a particular property.
More relevant for your scenario:
You will notice that child objects can be added to any Item-based type without explicitly adding them to the children property. This is because the default property of Item is its data property, and any items added to this list for an Item are automatically added to its list of children. Default properties can be useful for reassigning the children of an item. See the TabWidget Example, which uses a default property to automatically reassign children of the TabWidget as children of an inner ListView.
If you take a look at the TabWidget example that the last paragraph refers to, you should have all you need:
import QtQuick 2.0
Item {
id: tabWidget
// Setting the default property to stack.children means any child items
// of the TabWidget are actually added to the 'stack' item's children.
// See the "Property Binding"
// documentation for details on default properties.
default property alias content: stack.children
property int current: 0
onCurrentChanged: setOpacities()
Component.onCompleted: setOpacities()
function setOpacities() {
for (var i = 0; i < stack.children.length; ++i) {
stack.children[i].opacity = (i == current ? 1 : 0)
}
}
Row {
id: header
Repeater {
model: stack.children.length
delegate: Rectangle {
width: tabWidget.width / stack.children.length; height: 36
Rectangle {
width: parent.width; height: 1
anchors { bottom: parent.bottom; bottomMargin: 1 }
color: "#acb2c2"
}
BorderImage {
anchors { fill: parent; leftMargin: 2; topMargin: 5; rightMargin: 1 }
border { left: 7; right: 7 }
source: "tab.png"
visible: tabWidget.current == index
}
Text {
horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter
anchors.fill: parent
text: stack.children[index].title
elide: Text.ElideRight
font.bold: tabWidget.current == index
}
MouseArea {
anchors.fill: parent
onClicked: tabWidget.current = index
}
}
}
}
Item {
id: stack
width: tabWidget.width
anchors.top: header.bottom; anchors.bottom: tabWidget.bottom
}
}
In cases like this, where you want to replicate something that is done by an item offered by Qt, it can also be helpful to take a look at the source code of what you're trying to replicate. However, the documentation is a bit easier to read. :)
Upvotes: 3