Как связать ComboBox с другим ComboBox

Я пытаюсь сделать приложение-конвертер, зависящее от двух 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") }
            }
        }
    }

Когда текущий индекс выбран из первого поля со списком, второе поле со списком должно удалить текущий индекс. Когда из первого выбирается другой индекс, второй должен восстанавливать предыдущий индекс и динамически удалять текущий индекс. Например, если выбран счетчик, второе поле со списком должно быть {"миля", "км"}. Я знаю только очень длинный путь, который можно выполнить с комбинацией нескольких индексов, но мои данные поля со списком включают 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. Есть какое-нибудь решение? Спасибо


person Edip Ahmet    schedule 27.03.2018    source источник


Ответы (1)


Вы не можете изменить 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
                }
            }

        }
    }
person Yoann Quenach de Quivillic    schedule 27.03.2018