Qt QML:移动到窗体中的下一个控件

Qt QML:移动到窗体中的下一个控件,qt,qml,qtquick2,Qt,Qml,Qtquick2,如何在QML表单中将焦点从一个控件移动到下一个控件? 默认情况下,它使用选项卡按钮,但我需要将其更改为输入。 所有控件都是按两列的网格布局排序的。您可以使用: 使用键。按下onreturn和forceActiveFocus() 我定义了一个新组件TextFieldMoveOnReturn.qml import QtQuick 2.0 import QtQuick.Controls 1.1 TextField { Keys.onReturnPressed: nextItemInFocu

如何在QML表单中将焦点从一个控件移动到下一个控件? 默认情况下,它使用
选项卡
按钮,但我需要将其更改为
输入
。 所有控件都是按两列的网格布局排序的。

您可以使用:


使用
键。按下onreturn
forceActiveFocus()


我定义了一个新组件TextFieldMoveOnReturn.qml

import QtQuick 2.0
import QtQuick.Controls 1.1

TextField {
    Keys.onReturnPressed:  nextItemInFocusChain().forceActiveFocus()
}
import QtQuick 2.0
import QtQuick.Layouts 1.1

GridLayout {
    Keys.onReturnPressed: {
        for (var i = 0; i < children.length; ++i)
            if (children[i].focus) {
                children[i].nextItemInFocusChain().forceActiveFocus()
                break
            }
    }
}
如果使用此字段而不是TextField,则可以获得所需的行为

编辑更好的解决方案:定义新组件GridLayoutNextOnReturn.qml

import QtQuick 2.0
import QtQuick.Controls 1.1

TextField {
    Keys.onReturnPressed:  nextItemInFocusChain().forceActiveFocus()
}
import QtQuick 2.0
import QtQuick.Layouts 1.1

GridLayout {
    Keys.onReturnPressed: {
        for (var i = 0; i < children.length; ++i)
            if (children[i].focus) {
                children[i].nextItemInFocusChain().forceActiveFocus()
                break
            }
    }
}
导入QtQuick 2.0
导入QtQuick.Layouts 1.1
网格布局{
按键。按返回键:{
对于(变量i=0;i

并在内部使用普通文本字段-就像一个符咒一样工作

为了使其更加健壮和灵活,您应该做出同样的行为 对于
选项卡
输入/返回
键。
处理
keyPressed
事件,并使用
KeyNavigation.tab
而不是
nextiminFocusChain
聚焦下一个元素,如下所示:

import QtQuick 2.12
import QtQuick.Controls 1.12

Column {
    TextField {
        id: field1
        KeyNavigation.tab: field2
        activeFocusOnTab: true
        Keys.onReturnPressed: KeyNavigation.tab.forceActiveFocus();
    }
    TextField {
        id: field2
        KeyNavigation.tab: field3
        activeFocusOnTab: true
        Keys.onReturnPressed: KeyNavigation.tab.forceActiveFocus();
    }
    TextField {
        id: field3
        KeyNavigation.tab: field1
        activeFocusOnTab: true
        Keys.onReturnPressed: KeyNavigation.tab.forceActiveFocus();
    }
}
因此,您可以控制焦点顺序,用户可以交替使用
选项卡
返回
键,从而获得更好的用户体验
只要想更改订单,只需更改
KeyNavigation.tab
值:)


注意:我强烈建议您避免使用
nextItemInFocusChain
,因为将来会有变化和灵活性

当您添加第三个字段并在编辑第二个字段时单击第一个字段时,第一个和第三个字段都会聚焦。这不是OP要求的。然而,你能分享你所说的错误代码吗?是的,但这是Qt中的一个bug:你链接到的代码在修复后可以工作
forceActiveFocus()
并不是真的需要。嗯,没错。如果焦点工作正常,
forceActiveFocus()
与设置
focus=true
相同,因为父焦点作用域具有活动焦点。谢谢你提交错误报告。但<代码> OnEddieEngult仍然不是OP想要的,因为它也在鼠标离开到任何先前输入字段时触发。真的,他没有提到鼠标点击。假设这种代码,它是解决OP问题的正确方式,让我想知道我们从QT C++中松动“演进”的UX有多大。QML@CapelliC:“这种代码”?你在C++和QML之间失去了什么?C++等价物实际上是更多的编写代码(如果使用.h和.cpp文件的话)更多:@ MITCH:我错过的是覆盖元素行为的能力,以便能够提供不同的UX,保留声明性的、可重用的接口。您是否建议覆盖QML GridLayout?你在C++中翻译了QML的解决方案,但是我会寻找一种更声明的方式——也许已经从Qual对话或QWIDGET提供…如果还没有提供,在C++中我知道如何实现它。但在QML?这不仅仅是奇怪的离题哲学,他有一个很好的观点。我上面的解决方案可能有效,但仍然是糟糕的代码风格。例如,字段ID之间的固定连接不允许轻松添加或移动一个字段。你可以绕过它,自动获取继任者的id,但这会进一步降低可读性。谢谢,@capelical!
nextItemInFocusChain
对我来说真的是新鲜事。实际上这就是我想要的)基本上,所有的解决方案都与之相似;感谢所有参与者,你们的评论帮助我看到了问题的另一面。这比其他答案灵活得多(特别是第二种方法),而且似乎你们已经解决了西蒙答案评论中提到的自己的问题?是的,事实上,我试图用一个工作实例来说明为什么这个答案的方法不是那么好。顺便说一句,在本例中,QML有一个“随时可用”的解决方案,但我在视频处理方面有经验,在Linux和Android之间无法移植代码。我很难编写一个变通方案……不,我没有考虑报告它。我的解决方法相当复杂,但无论如何让我可以继续。。。我习惯于认为,如果我不能克服我发现的问题,我就不能真正理解一个平台。实际上,我希望QML可以是一个简单的声明C++的路径。这并不容易,但我现在知道这是最好的方法。这似乎不是正确的方法。它使键盘关闭并重新打开我的2台设备,因此键盘布局重置为英语。但当我在本机应用程序或web表单中按Enter/Next时,键盘保持打开状态,键盘布局不变。我想知道如何在QML中实现同样的效果。@Sassan:我在Ubuntu上测试过,这是一种桌面设备。唉,随着时间的推移和发布的流动,现在我无法运行Android工具包并测试您的问题。不过,这值得进一步研究。