Идея состоит в том, что компонент четко устанавливает входы и выходы, и в вашем случае компонент очень связан с представлением, поэтому он будет мало пригоден для повторного использования. Лучшим дизайном является предоставление только свойства, которое обновляется данными модели, а также уведомляет об этом, когда оно изменилось.
В делегате я предпочитаю использовать Loader для отображения редактора при необходимости.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>
#include <QDebug>
enum CustomRoles {
NameRole = Qt::UserRole + 1000,
StartRole,
EndRole
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QStandardItemModel model;
QObject::connect(&model, &QStandardItemModel::itemChanged, [](QStandardItem *item){
qDebug()<< item->data(StartRole);
});
QHash<int, QByteArray> roles;
roles[NameRole] = "name";
roles[StartRole] = "start";
roles[EndRole] = "end";
model.setItemRoleNames(roles);
for(int i=0; i<4; ++i){
QStandardItem *parent_item = new QStandardItem();
model.invisibleRootItem()->appendRow(parent_item);
parent_item->setData(QString("name-%1").arg(i), NameRole);
parent_item->setData(QString("start-%1").arg(i), StartRole);
parent_item->setData(QString("end-%1").arg(i), EndRole);
for (int j=0; j<5; ++j) {
QStandardItem *child_item = new QStandardItem();
parent_item->appendRow(child_item);
child_item->setData(QString("name-%1-%2").arg(i).arg(j), NameRole);
child_item->setData(QString("start-%1-%2").arg(i).arg(j), StartRole);
child_item->setData(QString("end-%1-%2").arg(i).arg(j), EndRole);
}
}
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("itemModel", &model);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TreeView {
id: treeView
anchors.fill: parent
TableViewColumn {
title: "Value"
role: "name"
delegate: EditorDelegate{
text: styleData.value
onTextChanged: model.name = text
}
}
TableViewColumn {
title: "Start"
id: start
role: "start"
delegate: EditorDelegate{
text: styleData.value
onTextChanged: model.start = text
}
}
TableViewColumn {
title: "End"
id: end
role: "end"
delegate: EditorDelegate{
text: styleData.value
onTextChanged: model.end = text
}
}
model: itemModel
}
}
EditorDelegate.qml
import QtQuick 2.0
Rectangle {
id: root
property string text
property bool mode: false
Component{
id: component_display
Text{}
}
Component{
id: component_edit
TextInput{}
}
Loader{
id: loader
anchors.fill: parent
sourceComponent: mode ? component_edit: component_display
onSourceComponentChanged: {
loader.item.text = root.text
if(sourceComponent === component_edit){
loader.item.editingFinished.connect(onEditingFinished)
loader.item.forceActiveFocus()
}
}
function onEditingFinished(){
text = loader.item.text
mode = false
}
MouseArea{
anchors.fill: parent
onDoubleClicked: {
if (mouse.button & Qt.LeftButton)
mode = true
}
}
}
}