【问题标题】:Maintain Focus on QML TextInput when Repeater Updates中继器更新时保持对 QML TextInput 的关注
【发布时间】:2019-01-18 20:39:01
【问题描述】:

我希望我的 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 移开。我希望用户能够顺利地将一个条目添加到列表中,然后将选项卡添加到新的空输入并添加另一个。将焦点设置在正在编辑的 TextInput 为 true 并使用 forceActiveFocus 方法似乎不起作用。有没有其他方法可以在更新后重新设置焦点?

【问题讨论】:

  • 这里有一些概念上的错误,您有一个 TextInput,它是由一个由模型(JS 数组)驱动的中继器创建的。但是,一旦您修改了该模型,Repeater 就会销毁并重新创建您的委托。一旦用户键入内容,您就会修改该模型。你想达到什么结果?
  • @peppe 你提到中继器代表被破坏帮助我意识到我做错了什么。谢谢!

标签: qt qml


【解决方案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": ""})
                        }
                    }
                }
            }
        }
    }
}

【讨论】:

  • 谢谢,我比我发布的解决方案更喜欢这个。我需要我的数据最终保存在一个 JS 数组中,但是在它和 ListModel 之间来回转换很容易。
【解决方案2】:

在多玩了一点焦点之后,我找到了一种让它按照我想要的方式工作的方法。代码如下:

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 的引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多