QML TreeView 的可重用编辑器委托



我正在尝试弄清楚如何为 QML TreeView组件创建可重用的EditorDelegate

我能够为一列创建一个可行的编辑器代表,角色为 end .但是我的TreeView有3列,即namestartend

我试图简单地设置styleData.value=textEdit.text而不是modelEnd=textEdit.text,但似乎styleData.value是一个只读属性。

如何使我的EditorDelegate对所有列都可重复使用?

EditorDelegate.qml 导入QtQuick 2.0

Rectangle {
    anchors.fill: parent
    Text {
        anchors.fill: parent
        id: textDisplay
        visible: true
        text: styleData.value
    }
    TextInput {
        anchors.fill: parent
        id: textEdit
        text: styleData.value
        visible: false
        onVisibleChanged: {
            focus: parent
        }
        onAccepted: {
            model.end=textEdit.text; // Can be model.name, model.start, model.<role>???
            textEdit.visible=false
            textDisplay.visible=true
        }
        onFocusChanged: {
            if (!focus) {
                textEdit.visible=false
                styleData.value=textEdit.text
                textDisplay.visible=true
            }
        }
    }
    MouseArea {
        id: mouseArea
        acceptedButtons: Qt.AllButtons
        anchors.fill: parent
        onDoubleClicked: {
            if (mouse.button & Qt.LeftButton) {
                textDisplay.visible=false
                textEdit.visible=true
                textEdit.forceActiveFocus()
            }
        }
    }
}

用法应该是这样的:

import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 1.4
Window {
    visible: true
    TreeView {
        id: treeView
        anchors.fill: parent
        TableViewColumn {
            title: "Value"
            role: "name"
            delegate: EditorDelegate { }
        }        
        TableViewColumn {
            title: "Start"
            id: start
            role: "start"
            delegate: EditorDelegate {   }
        }
        TableViewColumn {
            title: "End"
            id: end
            role: "end"
            delegate: EditorDelegate {  }
        }
        model: itemModel
    }
}

在这里我有另一个问题,因为EditorDelegate无法打开和折叠树节点。但这是一个完全不同的故事。

这个想法是组件清楚地建立入口和出口,在您的情况下,组件与视图非常相关,因此它几乎不可重用。更好的设计是仅公开使用模型数据更新的属性,并在模型发生更改时通知它。

在委托中,我更喜欢在必要时使用加载器来显示编辑器。

主.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();
}

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

相关内容

  • 没有找到相关文章

最新更新