将ListModel的特定项绑定到Component

时间:2017-04-07 22:50:44

标签: qt haskell qml hsqml

我正在使用HsQML构建应用程序。这是我第一次遇到QML,我在Qt的第二次工作,以及第一次与Haskell合作的大型项目,请原谅我的无知。

在UI中,我有一个TabView。第一个选项卡包含一个ListView,它绑定到模型并显示项目列表。双击ListView中的项目会打开一个新选项卡,其中包含一个正确显示该项目详细信息的组件(我的猜测是凭借新选项卡从单击的列表项继承其上下文)。

现在,我的目标是打开一个选项卡,在该选项卡中为该模型创建一个新项目。我们的想法是创建一个空白数据项(可选择将其添加到模型中),然后加载"加载"这与用于编辑现有项目的相同组件类型相同。我搜索了QML的文档,找不到任何与远程相关的内容,这让我觉得这种方法完全有缺陷。

TabView {
    id : rootTabs

    Tab {
        ListView {
            model : AutoListModel {
                source : workflowModel // this is sort of HsQML specific, data comes as a list from Haskell
            }
            delegate : Rectangle {
                Text {
                    text : modelData.name
                }

                MouseArea {
                    anchors.fill : parent

                    // this part works because the new component inherits its modelData from the current context
                    // so the new tab has correct data
                    onDoubleClicked : {
                        rootTabs.addTab(modelData.name, Qt.createComponent("WorkflowView.qml"))
                        rootTabs.currentIndex = rootTabsCount - 1
                    }
                }
            }
        }

        Button {
            text : "Create workflow"

            // this is the part in question - how do I assign the newly appended data to comp?
            onClicked : {
                wModel.appendBlank()
                comp = Qt.createComponent("WorkflowView.qml")
                var tab = rootTabs.addTab("New workflow", comp)
                comp.statusChanged.connect(tabLoaded)
            }
        }
    }
}

WorkflowEdit.qml:

Rectangle {
    TextField {
        id : nameInput
        text : modelData.name
        Binding {
            target : modelData
            property : "name"
            value : nameInput.text
        }
    }
}

2 个答案:

答案 0 :(得分:2)

TabView::addTab返回一个Tab对象,它基本上是一个Loader对象。 Loader::item是当前加载的对象。因此,解决方案是将新的空模型数据添加到选项卡,如下所示(在Button :: onClicked中):

var tab = ...
tab.loaded.connect(function () {tab.item.data = newModelData;}); // newModelData = wModel.appendBlank() ???

您应该将属性modelData显式添加到WorkflowEdit.qml:

Rectangle {
    property var data: modelData // create property data and assign the context variable modelData to it by default
    TextField {
        id : nameInput
        text : data === undefined ? "" : data.name
        Binding {
            target : data
            property : "name"
            value : nameInput.text
        }
    }
}

答案 1 :(得分:2)

我想我有你想要的东西。这有点棘手,因为Tab基本上是加载器。这是为Tab QML类型创建额外属性作为存储模型索引的位置的问题。由于选项卡只是TabView的子项,因此新选项卡可以作为TabView的父级,而不是使用addTab()方法。请注意,对于我的模型,我使用了ListModel。

<强> main.qml

import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480

    TabView {
        id : rootTabs
        anchors.fill: parent

        ListModel {
            id: listModel
            ListElement { car: "Toyota" }
            ListElement { car: "Chevrolet" }
            ListElement { car: "Honda" }
            ListElement { car: "Daihatsu" }
            ListElement { car: "Ford" }
            ListElement { car: "Nissan" }
            ListElement { car: "Hyundai" }
            ListElement { car: "Acura" }
        }

        MyTab {
            title: "Default"

            Item {

                ListView {
                    id: listView
                    anchors { fill: parent; bottomMargin: 240 }
                    model : listModel

                    delegate : Rectangle {
                        width: parent.width
                        height: 40
                        Text {
                            text : car
                            color: "black"
                            font.pointSize: 20
                        }

                        MouseArea {
                            anchors.fill : parent
                            onDoubleClicked : {
                                var myTab = Qt.createComponent("MyTab.qml")
                                var workflow = Qt.createComponent("Workflow.qml")
                                myTab.createObject(rootTabs, { "title": car, "modelIndex": index, "sourceComponent": workflow });
                                rootTabs.currentIndex = rootTabs.count - 1
                            }
                        }
                    }
                }

                Button {
                    anchors {fill: parent; topMargin: 240 }
                    text : "Create workflow"

                    onClicked : {
                        listModel.append( { "car" : "New car" } )
                        var myTab = Qt.createComponent("MyTab.qml")
                        var workflow = Qt.createComponent("Workflow.qml")
                        myTab.createObject(rootTabs, { "title": "New Workflow", "modelIndex": listModel.count - 1 , "sourceComponent": workflow });
                    }
                }
            }
        }
    }
}

<强> MyTab.qml

import QtQuick 2.0
import QtQuick.Controls 1.4

Tab {
    property int modelIndex
}

<强> Workflow.qml

import QtQuick 2.0
import QtQuick.Controls 1.4

Rectangle {
    TextField {
        id : nameInput
        text : listModel.get(modelIndex).car
        onTextChanged: {
            // Update model using modelIndex. Observe updates in listview
            listModel.set(modelIndex, { "car" : text })
        }
    }
}