如何 link 从 ComboBox 到另一个 ComboBox

How to link from ComboBox to another ComboBox

我尝试使用 Controls 2 制作一个依赖于两个组合框的转换器应用程序。 例如:

// 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,因此需要 JavaScript 和 JSON 列表模型,通过以下方式查找当前索引:

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

但我无法在 QML 中执行此操作。有什么解决办法吗?谢谢

您无法更改 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
                }
            }

        }
    }