2017-04-07 36 views
2

我正在用HsQML構建應用程序。這是我第一次遇到QML,我在Qt中的第二次工作,以及Haskell的第一個大型項目,所以請原諒我的無知。將特定項目的ListModel綁定到組件

在UI中,我有一個TabView。第一個Tab包含一個綁定到模型並顯示項目列表的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

你說的新標籤意味着有正確的數據?看起來你只是創建一個WorkflowView組件,就是這樣。你能發佈該qml文件的代碼嗎? –

+0

正確,我只是創建一個WorkflowView。但是,通過雙擊ListView項目創建它時,其modelData似乎包含該項目的相應數據......這是完全的魔術。 現在,我希望能夠以相同的方式進行編程,以便WorkflowView的'modelData'將引用我想要的模型中的項目。 添加了一個WorkflowView示例,無論如何這真的很簡單。 – RecencyEffect

回答

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 }) 
     } 
    } 
} 
+0

這樣做!似乎有兩個疑難問題 - ** 1)**在創建之後在選項卡的項目上設置屬性工作不正常,因此使用'createObject'手動解決該問題。這個imo的正確解決方案是將相同的配置暴露給'addTab',使得'addObject'具有(並且可能在幕後調用。** 2)**將任意對象分配給屬性失敗。我想知道這是否和我一起使用HsQML而不是自己創建'QObject'。解決方法是在'int'屬性中爲模型設置一個索引,然後每次查看。 – RecencyEffect

2

TabView::addTab返回一個Tab對象,這基本上是一個Loader對象。 Loader::item是當前加載的對象。所以,解決的辦法是一個新的空模型數據如下添加到選項卡(按鈕:: 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 
     } 
    } 
} 
+0

在創建函數和標籤的'statusChanged'處理程序中嘗試了這個,得到'錯誤:不能分配給不存在的屬性「modelData」'。還嘗試分配到'component.modelData'而不是標籤 - 這不顯示錯誤,但仍然不起作用,但WorkflowView中的modelData繼續未定義。 – RecencyEffect

+0

我擴展了我的答案來解決您提出的問題。 – m7913d

+0

Darn,我看到這應該如何解決未定義的屬性問題,但仍然不工作:(我得到一個'QML WorkflowEditView:綁定循環檢測到屬性「modelData」'(據我所知只是一個警告),還有當我激活選項卡:'TypeError:無法讀取未定義的屬性'名稱'對於後者,正如我已經提到的,我已經嘗試設置模型創建標籤,當標籤準備就緒,並且都不起作用。分配給component.modelData,因爲屬性是在組件上定義的,而不是在選項卡上定義的。 – RecencyEffect

相關問題