当前位置: 首页 > 知识库问答 >
问题:

在ListView之间传递焦点

骆利
2023-03-14

我正在创建一个支持多重选择的QMLListView,并将在我的应用程序中实例化其中的多个。我需要将键盘焦点赋予特定列表,处理该列表的按键,并根据焦点为选定的行绘制高亮显示。

但是,将focus=true赋予ListView委托或ListView本身并不会导致在ListView上出现ActiveFocus,也不会导致触发按键信号。

我创建了一个简单的示例应用程序,展示了我的问题:

import QtQuick 2.7
import QtQuick.Window 2.0

Window {
  id:window; visible:true; width:400; height:160; color:'darkgray'

  Component {
    id: row
    Rectangle {
      id: root
      property int  i: index
      property bool current: ListView.isCurrentItem
      property bool focused: ListView.view.activeFocus
      width:parent.width; height:20
      color: current ? ( focused ? 'pink' : 'lightblue' ) : 'lightgray'
      MouseArea {
        anchors.fill: parent
        onClicked: {
          root.ListView.view.currentIndex = i;
          root.ListView.view.focus = true;
        }
      }
      Text { anchors.fill:parent; text:modelData }
    }
  }

  Component {
    id: myList
    ListView {
      delegate: row
      width:window.width/2-10; height:window.height; y:5
      Keys.onUpPressed:   decrementCurrentIndex()
      Keys.onDownPressed: incrementCurrentIndex()
    }
  }

  Loader {
    sourceComponent:myList; x:5
    onLoaded: item.model = ['a','b','c','d']
  }
  Loader {
    sourceComponent:myList; x:window.width/2
    onLoaded: item.model = ['1','2','3','4','5']
  }
}

单击任一列表都不会将选定的行变成粉红色,按上/下键也不会调整选定内容。

如何将焦点传递给特定的ListView,以便(a)一次只有一个ListView持有该焦点,(b)我可以检测ListView何时持有该焦点,(c)它只允许键盘信号在聚焦时为该ListView工作?

我使用QT5.7,以防万一。

>

  • 在矩形而不是ListView上设置focus=true
  • focused属性设置为监视listview.view.focus而不是ActiveFocus:这允许两个列表同时变成粉红色。
  • 在Qt Quick中阅读键盘焦点,并在focusscope中包装矩形或ListView。(转发所有接口是多么痛苦。)

    >

  • 在白天重新读取页面,并将两个加载器包装在一个focusscope中。诅咒,因为两个ListView显然被允许同时聚焦,这违反了我对这一部分文档的阅读:

    在每个焦点范围内,一个对象可以将item::focus设置为true。如果多个项设置了focus属性,则最后一个设置焦点的类型将设置focus,其他类型将取消设置,类似于没有焦点作用域时的情况。

    将ListView包装在一个项中,并将Keys处理程序放在该项上,然后尝试聚焦该项。

    注意:我意识到标准的ListView使用高亮显示来显示选择,并使用键盘导航来调整CurrentiteM。但是,由于我的需要需要多个并发选择的项目,我必须特别管理高亮和键盘。

    编辑:这里有一个更简单的测试用例,它的行为并不像我所期望的那样:

    import QtQuick 2.7
    import QtQuick.Window 2.0
    
    Window {
      id:window; visible:true; width:400; height:160; color:'darkgray'
    
      FocusScope {
        Rectangle {
          width: window.width/2-6; height:window.height-8; x:4; y:4
          color: focus ? 'red' : 'gray'
          MouseArea { anchors.fill:parent; onClicked:parent.focus=true }
          Text { text:'focused'; visible:parent.activeFocus }
          Keys.onSpacePressed: console.log('space left')
        }
        Rectangle {
          width: window.width/2-6; height:window.height-8; x:window.width/2+2; y:4
          color: focus ? 'red' : 'gray'
          MouseArea { anchors.fill:parent; onClicked:parent.focus=true }
          Text { text:'focused'; visible:parent.activeFocus }
          Keys.onSpacePressed: console.log('space right')
        }
      }
    }
    

    编辑2:哇哦。如果我删除FocusScope,它将按预期工作:焦点仍然是独占的,ActiveFocus被授予,并且空间正常工作。上面的问题可能是因为listviewfocusscope(根据文档)。

    编辑3:根据Mitch下面的注释,在focusscope上设置focusscope,也可以使focusscope正常工作。然而,根据我下面的回答(和Mitch的评论),FocusScope并不是让我的任何一个简化的示例应用程序正常工作所必需的。

  • 共有1个答案

    姬飞昂
    2023-03-14

    如果打印出原始示例中的活动焦点项

    onActiveFocusItemChanged: print(activeFocusItem)
    

    你可以看到没有一个装载机得到焦点;它总是窗口的根项。

    如果在其中一个加载器上设置focus:true,那么它将具有焦点:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        id: window
        visible: true
        width: 400
        height: 160
        color: 'darkgray'
    
        onActiveFocusItemChanged: print(activeFocusItem)
    
        Component {
            id: row
            Rectangle {
                id: root
                property int i: index
                property bool current: ListView.isCurrentItem
                property bool focused: ListView.view.activeFocus
                width: parent.width
                height: 20
                color: current ? (focused ? 'pink' : 'lightblue') : 'lightgray'
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        root.ListView.view.currentIndex = i
                        root.ListView.view.focus = true
                    }
                }
                Text {
                    anchors.fill: parent
                    text: modelData
                }
            }
        }
    
        Component {
            id: myList
            ListView {
                delegate: row
                width: window.width / 2 - 10
                height: window.height
                y: 5
                Keys.onUpPressed: decrementCurrentIndex()
                Keys.onDownPressed: incrementCurrentIndex()
            }
        }
    
        Loader {
            objectName: "loader1"
            sourceComponent: myList
            focus: true
            x: 5
            onLoaded: item.model = ['a', 'b', 'c', 'd']
        }
        Loader {
            objectName: "loader2"
            sourceComponent: myList
            x: window.width / 2
            onLoaded: item.model = ['1', '2', '3', '4', '5']
        }
    }
    
    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        id: window
        visible: true
        width: 400
        height: 160
        color: 'darkgray'
    
        onActiveFocusItemChanged: print(activeFocusItem)
    
        Component {
            id: row
            Rectangle {
                id: root
                property int i: index
                property bool current: ListView.isCurrentItem
                property bool focused: ListView.view.activeFocus
                width: parent.width
                height: 20
                color: current ? (focused ? 'pink' : 'lightblue') : 'lightgray'
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        root.ListView.view.currentIndex = i
                        root.ListView.view.parent.focus = true
                        root.ListView.view.focus = true
                    }
                }
                Text {
                    anchors.fill: parent
                    text: modelData
                }
            }
        }
    
        Component {
            id: myList
            ListView {
                delegate: row
                width: window.width / 2 - 10
                height: window.height
                y: 5
                Keys.onUpPressed: decrementCurrentIndex()
                Keys.onDownPressed: incrementCurrentIndex()
            }
        }
    
        Loader {
            objectName: "loader1"
            sourceComponent: myList
            x: 5
            onLoaded: item.model = ['a', 'b', 'c', 'd']
        }
        Loader {
            objectName: "loader2"
            sourceComponent: myList
            x: window.width / 2
            onLoaded: item.model = ['1', '2', '3', '4', '5']
        }
    }
    

    在这一点上,我会放弃并强制主动集中注意力:

    import QtQuick 2.7
    import QtQuick.Window 2.2
    
    Window {
        id: window
        visible: true
        width: 400
        height: 160
        color: 'darkgray'
    
        onActiveFocusItemChanged: print(activeFocusItem)
    
        Component {
            id: row
            Rectangle {
                id: root
                objectName: ListView.view.objectName + "Rectangle" + index
                property int i: index
                property bool current: ListView.isCurrentItem
                property bool focused: ListView.view.activeFocus
                width: parent.width
                height: 20
                color: current ? (focused ? 'pink' : 'lightblue') : 'lightgray'
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        root.ListView.view.currentIndex = i
                        root.ListView.view.forceActiveFocus()
                    }
                }
                Text {
                    anchors.fill: parent
                    text: modelData
                }
            }
        }
    
        Component {
            id: myList
            ListView {
                objectName: parent.objectName + "ListView"
                delegate: row
                width: window.width / 2 - 10
                height: window.height
                y: 5
                Keys.onUpPressed: decrementCurrentIndex()
                Keys.onDownPressed: incrementCurrentIndex()
            }
        }
    
        Loader {
            id: loader1
            objectName: "loader1"
            sourceComponent: myList
            x: 5
            onLoaded: item.model = ['a', 'b', 'c', 'd']
        }
        Loader {
            objectName: "loader2"
            sourceComponent: myList
            x: window.width / 2
            onLoaded: item.model = ['1', '2', '3', '4', '5']
        }
    }
    

    我真的不喜欢对焦系统。我不是说我能想出更好的东西,但它只是不容易使用。

     类似资料:
    • voneController.java VotwoController.java

    • 我有一个JPanel表单,其中包含一个JList和一些JButton。JPanel看起来像这样 当我单击Add List按钮时,会显示一个单独的JFrame表单。JFrame表单将如下所示 单击JFrame上的add按钮时,我需要将JTextfield(命名列表名)的值添加到上一个JPanel上的JList。我想知道如何将值从JFrame传递到JPanel?如有任何建议,将不胜感激。 下面是 JP

    • 问题内容: 我有一个调用会弹出一个的,以便用户可以选择目录。这些都是单独的类。从中传递值的正确方法是什么,以便我可以在中显示目录的路径? 编辑:更新了问题。 问题答案: 这是一个不完整的示例,但我想可以使您了解如何实现所需的目标。重要的一点是引用要在其中进行选择的属性,例如 参见下面如何将其放置在代码中: 希望对您有所帮助,对不起您没有提供完整的示例。 编辑 本质上,我们没有将任何参数传递给Abs

    • 我正在开发一个由多个活动组成的Android应用程序,我必须在它们之间传递ab对象,但我不能通过使用意图传递它,因为对象的类没有实现可序列化,我怎么做?我无法修改我的类的源代码。谢谢:)

    • 问题内容: 抱歉,如果我的问题是菜鸟。我正在使用pgsql 8.4运行Django 1.2,并且需要在从用户处获得输入后运行Java程序,进行一些计算并将结果返回给用户。 我是否可以知道在Java和Python Django之间传递数据的最佳方法是什么,以便解决上述情况?我听说过Jython,但是根据Django文档,它需要扩展名jython- Django,但目前不支持django1.2.x。我

    • 问题内容: 以及Android文档: http://developer.android.com/training/basics/fragments/communicating.html 以及本文: http://manishkpr.webheavens.com/android-passing-data-between- fragments/ 尽管上述所有情况都与我的情况相似,但并不完全相同。我在这