当前位置: 首页 > article >正文

QML列表视图 ListView的使用

一个ListView可以显示来自由如ListModel和XmlListModel等内置 QML 类型创建的模型的数据,也可以用在 C++ 中定义的、继承自QAbstractItemModel或QAbstractListModel的自定义模型类的数据。
一个ListView要有一个模型,它定义了要显示的数据,还有一个委托,它定义了数据应该如何显示。ListView中的项可以水平或垂直布局。由于ListView继承自Flickable,所以列表视图也是可滑动的。

1. 简单使用

下面定义一个简单的数据模型(ListModel)和代理(本示例程序用Text),并用ListView来展示:


// 数据模型
ListModel {
    id: cusModel

    ListElement {
        name: "Tom"
        number: "11111"
    }

    ListElement {
        name: "Jerry"
        number: "22222"
    }

    ListElement {
        name: "Spike"
        number: "33333"
    }
}

ListView {
    id: view
    model: cusModel    // 指定模型
    width: 200
    height: parent.height

    delegate: Text {    // 自定义代理
        text: name + " -> " + number
    }
}

运行结果图如下:
在这里插入图片描述

2. 自定义代理

由于上述例子的代理仅仅是一个Text,实属太难看;下面我们将代理改良下,让它变得稍微好看点:


// 自定义代理项
Component {
    id: cusDelgate
    
    Item {
        width: 180
        height: 40

        Column {
            Text { text: '<b>名称:</b>' + name; color: "red";}
            Text { text: '<b>代号:</b> ' + number }
        }
    }
}

ListView {
    id: view
    model: cusModel  // 指定模型
    x: 20
    y: 20
    width: 200
    height: parent.height

    highlight: Rectangle { color: "lightsteelblue"; radius: 5 } // 高亮
    delegate: cusDelgate
    focus: true      // 设置为true则可以使用键盘上下键切换项,被选择的项以高亮显示

    // 框出ListView区域
    Rectangle {
        anchors.fill: parent
        color: "transparent"
        border.width: 1
        border.color: "black"
    }
}

运行结果如下图:
在这里插入图片描述ListView比较常用的一些属性:


orientation: ListView.Horizontal (默认为ListView.Vertical)
header  // 自定义列表标头(页眉)
footer  // 自定义页脚
spacing // 项与项之间间距
... 更多详细请参考Qt帮助文档

3.使用ListView写一个简单的联系人列表

运行结果如下图:
在这里插入图片描述
ListView主要代码:

ListView {
    id: listView
    width: 270
    model: 10
    clip: true

    anchors {
        top: parent.top
        left: parent.left
        bottom: parent.bottom
    }

    header: SearchBox {
        width: listView.width
    }

    delegate: ContactItem {
        id: contact
        width: listView.width
        height: 70
    }

    footer: Rectangle {
        id: footerRect
        width: ListView.view.width
        height: 30
        color: "lightblue"
        border.width: 1

        Text {
            anchors.centerIn: footerRect
            color: "red"
            text: "一共有 " + listView.count + " 项"
        }
    }
}

SearchBox代码:

import QtQuick 2.15
import QtQuick.Controls 2.15

Rectangle {
    id: root
    height: 85

    TextField {
        id: search
        width: 100
        color: "transparent"
        leftPadding: 40
        placeholderText: "搜索"
        font.pixelSize: 20

        anchors {
            fill: parent
            margins: 20
        }

        background: Rectangle {
            anchors.fill: parent
            border.width: 1
            border.color: "gray"
            color: "transparent"
            radius: width / 2

            Image {
                id: name
                x: 10
                y: (parent.height - height) / 2
                width: 20
                height: 20
                source: "qrc:/images/icon/search.svg"
            }
        }
    }
}

ContactItem代码:

import QtQuick 2.15
import QtQuick.Controls 2.15

Rectangle {
    id: root
    clip: true

    property bool selected: false       // 被选中
    onSelectedChanged: {
        if(selected) selectRect.width = 5
        else selectRect.width = 0
    }

    Component.onCompleted: {
        root.selected = true
    }

    // 分割线
    Rectangle {
        id: line
        color: "gray"
        width: parent.width
        height: 1
    }

    // 被选中时的状态矩形
    Rectangle {
        id: selectRect
        width: 10
        height: parent.height
        color: "blue"

        Behavior on width {
            PropertyAnimation {duration: 70}
        }
    }

    // 头像图片
    Rectangle {
        id: headImg
        width: parent.height - line.height
        height: width

        anchors {
            top: line.bottom
            left: selectRect.right
            leftMargin: 8
        }

        CusMaskShape {
            anchors.fill: parent
        }
    }

    // 名称及个性签名
    Column {
        id: txt
        height: parent.height

        anchors {
            left: headImg.right
            leftMargin: 10
            right: headImg.left
            top: line.top
            topMargin: {
                let topM = nameTxt.font.pixelSize + descTxt.font.pixelSize
                topM = (root.height - topM - line.height) / 2
                return topM;
            }
        }

        Text {
            id: nameTxt
            font.pixelSize: 20
            font.bold: true
            text: "Tom"
        }

        Text {
            id: descTxt
            font.pixelSize: 16
            font.bold: true
            text: "talk is cheap, show me the code!"
            color: "gray"
            elide: Text.ElideRight
        }
    }
}

4. 注意事项:

当要在代理中访问视图的属性时,最好不要使用父类属性绑定,例如:


ListView {
   id: listView
   // ...

   delegate: Item {
       // 不建议
       width: parent.width

       // 推荐
       width: listView.width
       width: ListView.view.width
       // ...
   }
}

http://www.kler.cn/news/364515.html

相关文章:

  • Appium环境搭建全流程(含软件)
  • Python异常检测- DBSCAN
  • uni-app 开发微信小程序,实现图片预览和保存
  • C++11 28-纯虚函数的默认实现 The default implementation of pure virtual functions
  • vue中使用 html2canvas绘制图片并下载
  • 后端消息推送方案方案(轮询,长轮询,websocket,SSE)
  • Jenkins + GitLab + Docker实现自动化部署(Java项目)
  • 深入了解 Pandas 中的数据:Series 和 DataFrame 的使用指南
  • 借助栈逆置单链表
  • 基于YOLOv8深度学习的高密度人脸智能检测与统计系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战、目标检测
  • 【golang】学习文档整理
  • OpenFace安装教程及踩坑记录 (Ubuntu20.04—2024.10.24)
  • ElasticSearch全文检索和倒排索引
  • 杂项笔记
  • 100种算法【Python版】第8篇——群体智能优化算法之人工蜂群算法
  • Docker容器的基础镜像:构建现代应用程序的基石
  • PYTHON实现麦克风实时传流语音听写
  • verilog函数和任务
  • 跳表:数据结构中的“快速通道”
  • 内容安全与系统构建加速,助力解决生成式AI时代的双重挑战
  • c# lambda表达式基础语法
  • java基础day04:方法(函数),练习
  • Android原生ROM出现WIFI显示网络连接受限,网络无法连接的问题
  • 一个vue3的待办列表组件
  • 【如何使用git将自己注释不上传到git服务器】
  • 博客搭建之路:hexo搜索引擎收录