我正在使用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
}
}
}
答案 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 })
}
}
}