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 来说有点不那么琐碎,但它们正在与该版本控制方案保持一致。