如何从ComboBox链接到另一个ComboBox

时间:2018-03-27 12:49:12

标签: qt qml qtquickcontrols2

我尝试根据使用Controls 2的两个ComboBox来制作转换器应用程序。  例如:

// First combobox is input unit:
ComboBox {
            id: res_combo1
            width: res_comborect1.width
            currentIndex: 0
            model: ListModel {
                id: model1
                ListItem { text: qsTr("meter") }
                ListItem { text: qsTr("mile") }
                ListItem { text: qsTr("km") }
            }
        }
    }
// Second combobox is output unit:
ComboBox {
            id: res_combo2
            width: res_comborect1.width
            currentIndex: 0
            model: ListModel {
                id: model2
                ListItem { text: qsTr("meter") }
                ListItem { text: qsTr("mile") }
                ListItem { text: qsTr("km") }
            }
        }
    }

当从第一个组合框中选择当前索引时,第二个组合框应该删除当前索引。当从第一个中选择另一个索引时,第二个应该恢复先前的索引,它应该动态地删除当前索引。例如,如果选择了仪表,则第二个组合框应为{" mile"," km"}  我只知道可以通过几个索引的组合执行很长的路,但我的组合框数据包括20项,所以我不能用这种方式。很长的路:

   function visible1(){
        if(res_combo1.currentIndex==0){
            return true
        }
        else{
            return false
        }
    }
    function visible2(){
        if(res_combo1.currentIndex==1){
            return true
        }
        else{
            return false
        }
    }
    function visible3(){
        if(res_combo1.currentIndex==2){
            return true
        }
        else{
            return false
        }
    }
// if meter is selected from first combobox, second combobox:
RowLayout{
       visible: parent.visible1()
    ComboBox {   
        id: outcombo1
        currentIndex: 0
        model: ListModel {
            id: model_o1
            ListElement { text: qsTr("mile") }
            ListElement { text: qsTr("km") }
        }
    }
   }
// if mile is selected from first combobox:
RowLayout{
       visible: parent.visible2()
    ComboBox {   
        id: outcombo1
        currentIndex: 0
        model: ListModel {
            id: model_o2
            ListElement { text: qsTr("meter") }
            ListElement { text: qsTr("km") }
        }
    }
   }
// if km is selected from first combobox:
RowLayout{
       visible: parent.visible3()
    ComboBox {   
        id: outcombo1
        currentIndex: 0
        model: ListModel {
            id: model_o3
            ListElement { text: qsTr("meter") }
            ListElement { text: qsTr("mile") }
        }
    }
   }

我认为我们无法动态更改ListItem,因此通过以下方式查找当前索引需要具有JSON列表模型的JavaScript:

function find(model, criteria) {
  for(var i = 0; i < model.count; ++i) if (criteria(model.get(i))) return i
  return null
}

但是我无法在QML中做到这一点。有什么解决方案吗?感谢

1 个答案:

答案 0 :(得分:2)

您无法更改ListItem,但可以更改ListModel本身。

ListModel {
    id: fromModel
    ListElement {text: "m" }
    ListElement {text: "mile" }
    ListElement {text: "km" }
}

ListModel {
    id: toModel

    function updateModel()
    {
        // Update model Here
    }
}

RowLayout
{
    anchors.centerIn: parent
    ComboBox
    {
        id: fromCombobox
        model: fromModel
        onCurrentIndexChanged: toModel.updateModel()
    }
    ComboBox
    {
        id: toComboBox
        model: toModel
    }
}

这样,每次第一个组合更改时,第二个组合的模型都会更新。

在更新模型2之前,请检查更新后组合2中先前选择的项目是否仍然可用,以便在重建模型2后恢复它。

    function updateModel()
    {
        // Save old selection
        var selectedFrom = fromModel.get(fromCombobox.currentIndex).text
        if(toComboBox.currentText != selectedFrom)
            var valueToRestore = toComboBox.currentText
        else
            valueToRestore = ""

        // Update model
        clear()
        for(var i=0; i<fromModel.count; i++)
        {
            if(i == fromCombobox.currentIndex)
                continue
            append(fromModel.get(i))
        }

        //Restore selection
        for(var i=0; i<toModel.count; i++)
        {
            // If no value to restore, select first available
            if(valueToRestore == "")
            {
                if(toModel.get(i).text != selectedFrom)
                {
                    toComboBox.currentIndex = i
                    break
                }
            }

            // Else, restore previously selected item
            else
            {
                if(toModel.get(i).text == valueToRestore)
                {
                    toComboBox.currentIndex = i
                    break
                }
            }

        }
    }