中继器更新时保持对QML TextInput的关注

时间:2019-01-18 20:39:01

标签: qt qml

我希望我的QML代码在文本输入中显示字符串列表,并且在列表末尾始终有一个空文本输入。我几乎可以使用以下代码:

import QtQuick 2.11
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480

    property var values: ['test1','test2',''];

    Column {
        id: column
        anchors.fill: parent

        Repeater {
            id: repeater
            model: values
            Rectangle {
                border.width: 1
                border.color: "black"
                width: column.width
                height: childrenRect.height
                TextInput {
                    id: textField
                    text: qsTr(modelData)
                    width: column.width
                    onTextEdited: {
                        values[index] = textField.text;
                        if(values[values.length - 1] !== '') {
                            values.push('');
                            repeater.model = values;
                            textField.forceActiveFocus(); //doesn't work
                            textField.focus = true; //doesn't work
                        }
                    }
                }
            }
        }
    }
}

唯一的问题是,当您开始输入空的TextInput时,在将新的空输入添加到列表末尾后,应用程序会将焦点从该TextInput移开。我希望用户能够顺利地将一个条目添加到列表中,然后使用Tab键选择新的空输入并添加另一个。将焦点设置为正被编辑为true的TextInput上,并使用forceActiveFocus方法似乎无效。还有其他方法可以在更新后重新设置焦点吗?

2 个答案:

答案 0 :(得分:1)

如您所见,问题在于将列表用作模型,Repeater可以将列表用作模型,但只能用于读取。一种更有效的解决方案是使用ListModel,因为它可以简化其逻辑。

import QtQuick 2.11
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    ListModel {
        id: mymodel
        ListElement{
            text: "test1"
        }
        ListElement{
            text: "test2"
        }
        ListElement{
            text: ""
        }
    }
    Column {
        id: column
        anchors.fill: parent
        Repeater {
            id: repeater
            anchors.fill: parent
            model: mymodel
            Rectangle {
                width: repeater.width
                height: childrenRect.height
                border.width: 1
                border.color: "black"
                TextInput{
                    id: textinput
                    text: modelData
                    width: parent.width
                    property int my_index: index
                    onTextEdited: {
                        modelData = textinput.text
                        if(textinput.text != "" && mymodel.count == (textinput.my_index + 1)){
                            mymodel.append({"text": ""})
                        }
                    }
                }
            }
        }
    }
}

答案 1 :(得分:0)

在关注焦点之后,我找到了一种使它按我想要的方式工作的方法。这是代码:

import QtQuick 2.11
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480

    property var values: ['test1','test2',''];

    Column {
        id: column
        anchors.fill: parent

        Repeater {
            id: repeater
            model: values
            Rectangle {
                border.width: 1
                border.color: "black"
                width: column.width
                height: childrenRect.height
                TextInput {
                    id: textField
                    text: qsTr(modelData)
                    width: column.width
                    onTextEdited: {
                        values[index] = textField.text;
                        if(values[values.length - 1] !== '') {
                            values.push('');
                            var c = column;
                            repeater.model = values;
                            c.children[c.children.length-3].children[0].forceActiveFocus();
                        }
                    }
                }
            }
        }
    }
}

基本上,正如peppe在他的评论中说的那样,在更新Repeater模型时,销毁并重新创建了由Repeater创建的对象。因此,我最初在引用被破坏的对象的过程中永远无法工作。有效的方法获得对通过查看Repeater父级的子级创建的新TextInputs的引用。