Qt QML 在显示 StackView 页面时聚焦项目(TextField)
Qt QML Focus an Item (TextField) when showing a StackView Page
我想在加载 QML 文件时启用 TextField
焦点。但是,它不起作用。加载 TestUi.qml 文件后,我放置了一些按钮及其 onClick()
方法 _recipientView.focus = true_
,它工作正常。问题是第一次加载视图时没有启用默认焦点。
TestUi.qml
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.0
Page {
function init() {
recipientView.focus = true;
}
TextField {
id: recipientView
Layout.fillWidth: true
font.pixelSize: 18
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhEmailCharactersOnly
focus: true
placeholderText: "Email"
}
}
main.qml
onComposeBtnClicked: {
rootStackView.push(test)
test.init()
}
TestUi {
id: test
visible: false
}
编辑
Page
组件已充当 FocusScope
,因此只需要强制激活焦点。感谢评论。
StackView {
id: stackView
initialItem: firstPage
// Ensures the focus changes to your page whenever
// you show a different page
onCurrentItemChanged: {
currentItem.forceActiveFocus()
}
}
Page {
id: firstPage
visible: false
TextField {
// Explicitly set the focus where needed
focus: true
}
}
原回答
这仅仅是因为您使用 rootStackView.push(test)
将 TestUi
推入堆栈。当您这样做时,焦点将被重置。这通常用 QFocusScope
处理,其作用是记住焦点 Item
,并在 QFocusScope
重新获得焦点时将焦点还给它。
对于您的情况,将 QFocusScope
添加到您的基本页面将能够在页面显示时正确恢复焦点:
StackView {
id: stackView
initialItem: firstPage
onCurrentItemChanged: {
currentItem.forceActiveFocus()
}
}
Page {
id: firstPage
visible: false
onFocusChanged: {
scope.focus = true
}
FocusScope {
id: scope
TextField {
focus: true
// ...
}
}
}
如果您想在用户返回时(例如弹出窗口后)重新设置焦点,而不是记住焦点所在的位置,则可以使用您的页面处理程序 onVisibleChanged
。但在那种情况下,FocusScope
可能有点矫枉过正。
参考,您也可以使用StackView
属性initialItem
来设置第一页。
它也有点不相关,但更喜欢 import
可用的最新版本的 QtQuick 组件。对于 Qt 5.12,QtQuick 版本将为 2.12。对于 QtQtcuik.Controls version 来说有点不那么琐碎,但它们正在与该版本控制方案保持一致。
我想在加载 QML 文件时启用 TextField
焦点。但是,它不起作用。加载 TestUi.qml 文件后,我放置了一些按钮及其 onClick()
方法 _recipientView.focus = true_
,它工作正常。问题是第一次加载视图时没有启用默认焦点。
TestUi.qml
import QtQuick 2.0
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.0
Page {
function init() {
recipientView.focus = true;
}
TextField {
id: recipientView
Layout.fillWidth: true
font.pixelSize: 18
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhEmailCharactersOnly
focus: true
placeholderText: "Email"
}
}
main.qml
onComposeBtnClicked: {
rootStackView.push(test)
test.init()
}
TestUi {
id: test
visible: false
}
编辑
Page
组件已充当 FocusScope
,因此只需要强制激活焦点。感谢评论。
StackView {
id: stackView
initialItem: firstPage
// Ensures the focus changes to your page whenever
// you show a different page
onCurrentItemChanged: {
currentItem.forceActiveFocus()
}
}
Page {
id: firstPage
visible: false
TextField {
// Explicitly set the focus where needed
focus: true
}
}
原回答
这仅仅是因为您使用 rootStackView.push(test)
将 TestUi
推入堆栈。当您这样做时,焦点将被重置。这通常用 QFocusScope
处理,其作用是记住焦点 Item
,并在 QFocusScope
重新获得焦点时将焦点还给它。
对于您的情况,将 QFocusScope
添加到您的基本页面将能够在页面显示时正确恢复焦点:
StackView {
id: stackView
initialItem: firstPage
onCurrentItemChanged: {
currentItem.forceActiveFocus()
}
}
Page {
id: firstPage
visible: false
onFocusChanged: {
scope.focus = true
}
FocusScope {
id: scope
TextField {
focus: true
// ...
}
}
}
如果您想在用户返回时(例如弹出窗口后)重新设置焦点,而不是记住焦点所在的位置,则可以使用您的页面处理程序 onVisibleChanged
。但在那种情况下,FocusScope
可能有点矫枉过正。
参考,您也可以使用StackView
属性initialItem
来设置第一页。
它也有点不相关,但更喜欢 import
可用的最新版本的 QtQuick 组件。对于 Qt 5.12,QtQuick 版本将为 2.12。对于 QtQtcuik.Controls version 来说有点不那么琐碎,但它们正在与该版本控制方案保持一致。