如何编写具有 return 值的 QML 键盘
HowTo write a QML-Keyboard with return value
我在我的 QML 应用程序的 ListView 中使用了很多 TextInput。要修改我提供的虚拟 QML 键盘的值,它还包含一个 TextInput。
当我单击 ListView 中的 TextInput 时,QML-Keyboard 中的 TextInput 获得焦点,用户可以开始编辑。完成后,文本应发送到 ListView 中的 TextInput。
我遇到的问题是,我不知道如何将键盘的 TextInput 的文本复制到 ListView 的 TextInput,因为启动虚拟键盘时焦点丢失了。
ListView
中的每个委托项都由其附加的 index
明确标识 属性。列表中的第一个委托的索引为 0,然后是 1,依此类推。
A ListView
有一个 属性 currentIndex
引用当前 selected 项目委托。当 currentIndex
设置为特定委托时,currentItem
属性 也设置为相应的委托对象。
鉴于这些属性,您可以利用它们来获得所需的行为。当你select一个TextInput
编辑它时,你可以将列表的currentIndex
设置为TextInput
委托的索引。这样也设置了 currentItem
,当虚拟键盘中的编辑完成时,它可以稍后用于引用委托(和内部的 TextInput
)。
这里有一个例子可以更好地解释我的观点:
import QtQuick 2.3
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
Window {
width: 200
height: 300
visible: true
Component {
id: myDelegate
Rectangle {
width: myList.width; height: 20
color: myList.currentIndex === index ? "lightgreen" : "lightgray" // distinguish the selecte delegate
onFocusChanged: textInput.forceActiveFocus()
property alias textInput: textInput // alias the textInput // (1)
TextInput {
id: textInput
anchors.fill: parent
onCursorVisibleChanged: {
if(cursorVisible)
{
myList.currentIndex = index // (2)
keyboardInput.text = textInput.getText(0, textInput.text.length) // (3)
keyboardInput.forceActiveFocus()
}
}
}
}
}
ColumnLayout {
anchors.fill: parent
ListView {
id: myList
model: 5
delegate: myDelegate
spacing: 10
Layout.fillWidth: true
Layout.fillHeight: true
}
Rectangle {
Layout.alignment: Qt.AlignBottom
color: "steelblue"
Layout.preferredWidth: parent.width
Layout.preferredHeight: 40
TextInput {
anchors.centerIn: parent // simulate the keyboard
id: keyboardInput
width: parent.width
font.pixelSize: parent.height
onEditingFinished: {
myList.currentItem.textInput.text = getText(0, text.length) //(4)
}
}
}
}
}
这是一个简化的示例,其中您的虚拟键盘被 ID 为 keyboardInput
的蓝色 TextInput
替代。每次列表中的 TextInput
获得焦点时,焦点将传递给 keyboardInput
以编辑文本。
首先,委托中的 TextInput
是别名 (1),以便可以从委托外部访问。当列表中的 TextInput
获得焦点进行编辑时(在我的例子中,我考虑 CursorVisibleChanged
事件),列表 currentIndex
被设置为委托的 index
(2 ) 并且 TextInput
中的当前文本也被复制到 keyboardInput
(3) 中。编辑完成后,keyboardInput
中的文本将通过 currentitem
(4).
复制回当前 selected TextInput
这种方法甚至适用于多个 ListView
:只需将当前列表存储在更高范围的变量中,然后在 (4) 中引用该变量以在正确的委托中设置文本。
我在我的 QML 应用程序的 ListView 中使用了很多 TextInput。要修改我提供的虚拟 QML 键盘的值,它还包含一个 TextInput。
当我单击 ListView 中的 TextInput 时,QML-Keyboard 中的 TextInput 获得焦点,用户可以开始编辑。完成后,文本应发送到 ListView 中的 TextInput。
我遇到的问题是,我不知道如何将键盘的 TextInput 的文本复制到 ListView 的 TextInput,因为启动虚拟键盘时焦点丢失了。
ListView
中的每个委托项都由其附加的 index
明确标识 属性。列表中的第一个委托的索引为 0,然后是 1,依此类推。
A ListView
有一个 属性 currentIndex
引用当前 selected 项目委托。当 currentIndex
设置为特定委托时,currentItem
属性 也设置为相应的委托对象。
鉴于这些属性,您可以利用它们来获得所需的行为。当你select一个TextInput
编辑它时,你可以将列表的currentIndex
设置为TextInput
委托的索引。这样也设置了 currentItem
,当虚拟键盘中的编辑完成时,它可以稍后用于引用委托(和内部的 TextInput
)。
这里有一个例子可以更好地解释我的观点:
import QtQuick 2.3
import QtQuick.Window 2.0
import QtQuick.Layouts 1.1
Window {
width: 200
height: 300
visible: true
Component {
id: myDelegate
Rectangle {
width: myList.width; height: 20
color: myList.currentIndex === index ? "lightgreen" : "lightgray" // distinguish the selecte delegate
onFocusChanged: textInput.forceActiveFocus()
property alias textInput: textInput // alias the textInput // (1)
TextInput {
id: textInput
anchors.fill: parent
onCursorVisibleChanged: {
if(cursorVisible)
{
myList.currentIndex = index // (2)
keyboardInput.text = textInput.getText(0, textInput.text.length) // (3)
keyboardInput.forceActiveFocus()
}
}
}
}
}
ColumnLayout {
anchors.fill: parent
ListView {
id: myList
model: 5
delegate: myDelegate
spacing: 10
Layout.fillWidth: true
Layout.fillHeight: true
}
Rectangle {
Layout.alignment: Qt.AlignBottom
color: "steelblue"
Layout.preferredWidth: parent.width
Layout.preferredHeight: 40
TextInput {
anchors.centerIn: parent // simulate the keyboard
id: keyboardInput
width: parent.width
font.pixelSize: parent.height
onEditingFinished: {
myList.currentItem.textInput.text = getText(0, text.length) //(4)
}
}
}
}
}
这是一个简化的示例,其中您的虚拟键盘被 ID 为 keyboardInput
的蓝色 TextInput
替代。每次列表中的 TextInput
获得焦点时,焦点将传递给 keyboardInput
以编辑文本。
首先,委托中的 TextInput
是别名 (1),以便可以从委托外部访问。当列表中的 TextInput
获得焦点进行编辑时(在我的例子中,我考虑 CursorVisibleChanged
事件),列表 currentIndex
被设置为委托的 index
(2 ) 并且 TextInput
中的当前文本也被复制到 keyboardInput
(3) 中。编辑完成后,keyboardInput
中的文本将通过 currentitem
(4).
TextInput
这种方法甚至适用于多个 ListView
:只需将当前列表存储在更高范围的变量中,然后在 (4) 中引用该变量以在正确的委托中设置文本。