【问题标题】:Pass ListView currentItem info to external component将 ListView currentItem 信息传递给外部组件
【发布时间】:2015-10-05 13:01:41
【问题描述】:

我正在使用 Qt 逻辑作为主干应用程序开发 QML,我遇到以下情况: 在启动时,QML ApplicationWindow 与其StatusBar 一起显示,其中包含两个状态图标和一个可检查的Button,名为UeStaffSelector 用于工作人员登录。当我按下UeStaffSelector 时,弹出Window 名为ueStaffView(它包含ListView 名为ueListViewWorkers)并从ueListViewWorkers 中选择用户进行登录过程,如下图所示:

现在,我有另一个自定义 QML Item,命名为 UeKeypad,代表用户的 pin 输入,因此他/她可以成功登录系统。这个UeKeypad必须在delegateListView中选择后弹出。 问题是,我在哪里打电话给UeKeypad?来自delegateListViewApplicationWindow?另外,如何将用户信息(用户图像、用户名和用户密码)传递给UeKeypad

【问题讨论】:

    标签: qt qml qtquick2 qt-signals


    【解决方案1】:

    QML 绑定很酷,非常酷。您可以声明键盘类型与当前委托中的类型(即当前Image 和用户/密码)之间的直接连接,而不是强制传递数据。这样一来,只要选择了一个委托,就会设置小键盘内的相应变量。

    这个结果可以使用States 来实现。我们定义了两个States,一个VISIBLE 状态用于向用户显示图像/用户名的键盘,一个HIDDEN 状态用于隐藏键盘,当没有可用选择时。明智地使用when 子句,即以互斥的方式,我们可以确保默认的空字符串State 永远不会被命中,因此组件的整体state 始终是一致的。

    使用States 的一个副作用是我们可以很容易地定义一个Transition 在两个States 之间移动,从而定义您感兴趣的滑动效果。此外,通过定义所有以声明的方式关联,仍然可以使用设计器编辑/查看表单。这对于命令式代码是不可能的。

    可以通过以下方式访问当前委托中的实际值 currentItem 中的值(aliased 如果在顶级类型中不可用)或通过模型get。请注意index 的用法,这是RepeaterListView 的附加属性。

    以下示例总结了这种方法,还提供了访问ListView 数据的两种方式。

    import QtQuick 2.0
    import QtQuick.Controls 1.3
    import QtQuick.Extras 1.4
    import QtQuick.Layouts 1.2
    import QtQuick.Window 2.2
    
    ApplicationWindow {
        width: 600
        height: 800
        visible: true
    
        Column {
            id: keypad
            x: parent.width - width     // put in the corner
            z: 2
            Row {
                width: 200
                spacing: 10
                Image {
                    id: keyImage
                    width: 100
                    height: 100
                }
                Text {
                    id: keyText
                    anchors.verticalCenter: parent.verticalCenter
                    font.pixelSize: 30
                }
            }
    
            Grid{
                columns: 3
                columnSpacing: 5
                rowSpacing: 5
                Repeater {
                    model: 9
                    Button {
                        text: index + 1
                        onClicked: console.info(text + " " + keyText.text)
                    }
                }
            }
    
            states: [
                State {
                    name: "HIDDEN"
                    PropertyChanges {
                        target: keypad
                        y: keypad.parent.height
                    }
                    when: list.currentIndex < 0
                },
                State {
                    name: "VISIBLE"
                    PropertyChanges {
                        target: keypad
                        y: keypad.parent.height / 2 - keypad.height / 2
                    }
                    PropertyChanges {
                        target: keyImage
                        source: list.model.get(list.currentIndex).image//list.currentItem.imagePath
                    }
                    PropertyChanges {
                        target: keyText
                        text: list.model.get(list.currentIndex).user//list.currentItem.label
                    }
                    when: list.currentIndex >= 0
                }
            ]
    
            transitions: Transition {
                NumberAnimation {
                    properties: "y";
                    duration: 1000
                    easing.type: Easing.InQuad
                }
            }
        }
    
    
        ListView {
            id: list
            anchors.fill: parent
            currentIndex: -1
            model: ListModel{
                ListElement {
                    image: "http://www.theapricity.com/forum/image.php?u=9098&dateline=1442619767"
                    user: "first"
                }
    
                ListElement {
                    image: "http://a.dilcdn.com/bl/wp-content/uploads/sites/8/2013/10/angry-cat-200x200.jpg"
                    user: "second"
                }
    
                ListElement {
                    image: "http://images.all-free-download.com/images/graphicthumb/walking_sand_cat_516744.jpg"
                    user: "third"
                }
            }
    
            delegate: Rectangle {
                width: ListView.view.width
                height: 220
                property alias imagePath: img.source
                property alias label: label.text
                RowLayout {
                    anchors.fill: parent
                    Image {
                        id: img
                        width: 100
                        height: 100
                        fillMode: Image.PreserveAspectFit
                        source: image
                        Layout.alignment: Qt.AlignLeft
                        Layout.preferredWidth: 100
                    }
    
                    Text {
                        id: label
                        Layout.fillWidth: true
                        Layout.alignment: Qt.AlignCenter
                        text: user
                        font.pixelSize: 30
                    }
                    MouseArea{
                        anchors.fill: parent
                        onClicked: list.currentIndex = index   //set the current item
                    }
                }
                color: ListView.isCurrentItem  ? "steelblue" : "transparent"
                scale: ListView.isCurrentItem ? 1 : 0.7
            }
        }
    }
    

    正如我们上面所讨论的,这种方法显然比命令式方法具有许多优点。主要是因为在 QML 中定义(某种)执行工作流的更自然方式。您仍然可以(有时更容易)为此目的定义命令式代码。请注意,在大多数情况下,如果您遵循命令式的方式,那么您只是“做错了”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 2019-08-09
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      相关资源
      最近更新 更多