将ListView currentItem信息传递给外部组件

时间:2015-10-05 13:01:42

标签: qt qml qtquick2 qt-signals

我正在使用Qt逻辑作为主干应用程序进行QML,我有以下情况: 在启动时,QML ApplicationWindow显示为StatusBar,其中包含两个状态图标和一个可检查的Button,名为UeStaffSelector,用于工作人员登录。当我按UeStaffSelector时,会弹出名为Window的{​​{1}}(其中包含名为ueStaffView的{​​{1}}},并选择ListView用户进行登录,如下面的屏幕截图所示:

User List Screenshot

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

1 个答案:

答案 0 :(得分:2)

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

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

使用State的副作用是我们可以轻松定义Transition以在两个State之间移动,从而定义您感兴趣的滑动效果类型。此外,通过以声明方式定义所有相关性,仍然可以使用设计者编辑/查看表单。使用命令式代码是不可能的。

可以通过访问当前委托内的实际值 currentItemalias ed中的值(如果在顶级类型中不可用)或通过模型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中的(某种)执行工作流程。您仍然可以(有时更容易)为此目的定义命令性代码。请注意,在大多数情况下,如果您遵循命令性方式,那么您只是“做错了”#34;。