• QT·ListView 的增删改查实现


    目录

    一、访问数据

    二、删除数据

    三、修改数据

    四、添加数据


    使用 ListView 是为了向用户展示某些数据,期望用户根据这些数据做出一些反馈,比如买某个东西。而我们会经常需要访问、修改一个 ListView 展现的数据。现在我们就来看看怎么做。

    一、访问数据

    ListModel 的 count 属性表示 Model 中有多少条数据,int 类型。dynamicRoles 属性为布尔值,为 true 时表示 Model 中的 role 对应的值的类型可以动态改变,默认值是 false。要设置 dynamicRoles,必须在添加数据之前。不过要注意的是,一旦你使能了 dynamicRoles,ListModel 的性能会大大下降,通常它带来的性能损失是使用静态类型的 4〜6 倍。

    ListModel 的get()方法接受一个 int 类型的参数,用来获取指定索引位置的数据,返回一 个 QML 对象。然后,我们就可以像访问属性那样访问数据的 role 了,正如我们在前面使用的那样:

    1. var data = listView.model.get(listView.currentIndex}
    2. listView.footerltem.text = data.name + " , " + data.cost + " , " + data.manufacturer

    二、删除数据

    如果你想删除一条或多条数据,可以使用 ListModel 的remove(int index, int count)方法,它有两个整型参数,第一个参数指明要删除的数据的索引位置,第二个参数表示要删除的数据条数,默认值为 1。

    如果你想清空一个 Model,可以直接调用 clear() 方法。

    现在我们将 phone_list_footer.qml 另存为 phone_list_change.qml,将 phoneDelegate 内的 MouseArea 对象修改为下面的样子:

    1. MouseArea {
    2. anchors.fill: parent
    3. onClicked: {
    4. wrapper.ListView.view.currentlndex = index
    5. }
    6. onDoubleClicked: {
    7. wrapper.ListView.view.model.remove(index)
    8. }
    9. }

    然后执行 “qmlscene phone_list_change.qml” 命令,用鼠标左键双击某个 Item,该 Item 就会从 ListView 中删除。

    让我们再修改一下 footer 组件,添加一个清除按钮,用来清除所有的数据。footer 组件的新代码如下:

    1. Component {
    2. id: footerView
    3. Item{
    4. id: footerRootItem
    5. width: parent.width
    6. height: 30
    7. property alias text: txt.text
    8. signal clean()
    9. Text {
    10. anchors.left: parent.left
    11. anchors.top: parent.top
    12. anchors.bottom: parent.bottom
    13. id: txt
    14. font.italic: true
    15. color: "blue"
    16. verticalAlignment: Text.AlignVCenter
    17. }
    18. Button {
    19. id: clearAll
    20. anchors.right: parent.right
    21. anchors.verticalCenter: parent.verticalCenter
    22. text: "Clear"
    23. onClicked: footerRootItem.clean()
    24. }
    25. }
    26. }

    给 ListView 添加 Component.onCompleted 附加信号处理器:

    1. Component.onCompleted: {
    2. listView.footerItem.clean.connect(listView.model.clear)
    3. }

    现在可以运行 phone_list_change.qml 了,看到界面右下角的 “Clear” 按钮了吧,点击它,列表所有数据就没啦。

    三、修改数据

    要想修改 Model 的数据,可以使用 ListModel 的setProperty(int index,string property, variant value)方法。该方法有三个参数,第一个是数据的索引,第二个是数据内 role 的名字,第三个是mle的值。比如要修改 “MI 2S" 的价格,可以这样:

    listView.model.setProperty(5, "cost", 16999)
    

    如果想替换某一条数据,可以使用set(int index, jsobject dict)方法。我们经常用对象的字面量表示法构造一个对象传递给 set() 方法。比如想把 “iPhone 3GS” 替换为 “Z5S mini”,可以这样:

    listView.model.set(0, {"name" : "25S mini ", "cost" : 1999, "manufacturer"  : "ZhongXing"})
    

    四、添加数据

    要向 Model 的尾部添加数据,可以使用append()方法。append() 的参数是 jsobject,在 ECMAScript 中可以使用对象的字面量表示法来构造这个 jsobject,即花括号加 key-value 对的 集合,类似于这样:{"name" : "zhangsan", "age" : 28},key-value 对之间使用逗号分隔。这种方式与 QML 对象声明的方式略有不同。给个简单的例子:

    1. function addOne(){
    2. model.append(
    3. {
    4. "name": "MX3",
    5. "cost": "1799",
    6. "manufacturer": "MeiZu"
    7. }
    8. );
    9. }

    如果想在指定位置添加数据,可以使用insert()方法,它的第一个参数是整型的,代表插 入的索引位置,第二个参数是 jsobject。

    再来修改下phone_list_change.qml,新增添加数据的代码,全新的内容如下:

    1. import QtQuick 2.2
    2. import QtQuick.Window 2.15
    3. import QtQuick.Controls 1.2
    4. import QtQuick.Layouts 1.1
    5. Window {
    6. width: 640
    7. height: 480
    8. visible: true
    9. title: qsTr("Hello World")
    10. Rectangle {
    11. width: 360
    12. height: 300
    13. color: "#EEEEEE"
    14. Component {
    15. id: headerView
    16. Item {
    17. width: parent.width
    18. height: 30
    19. RowLayout {
    20. anchors.left: parent.left
    21. anchors.verticalCenter: parent.verticalCenter
    22. spacing: 8
    23. Text {
    24. text: "Name" + "\t" + "Cost" + "\t" + "Manu"
    25. font.bold: true
    26. font.pixelSize: 20
    27. Layout.preferredWidth: 120
    28. }
    29. }
    30. }
    31. }
    32. Component {
    33. id: footerView
    34. Item{
    35. id: footerRootItem
    36. width: parent.width
    37. height: 30
    38. property alias text: txt.text
    39. // 1.自定义信号
    40. signal clean()
    41. signal add()
    42. Text {
    43. anchors.left: parent.left
    44. anchors.top: parent.top
    45. anchors.bottom: parent.bottom
    46. id: txt
    47. font.italic: true
    48. color: "blue"
    49. verticalAlignment: Text.AlignVCenter
    50. }
    51. Button {
    52. id: clearAll
    53. anchors.right: parent.right
    54. anchors.verticalCenter: parent.verticalCenter
    55. text: "Clear"
    56. onClicked: footerRootItem.clean()
    57. }
    58. Button {
    59. id: addOne
    60. anchors.right: clearAll.left
    61. anchors.rightMargin: 4
    62. anchors.verticalCenter: parent.verticalCenter
    63. text: "Add"
    64. onClicked: footerRootItem.add()
    65. }
    66. }
    67. }
    68. Component {
    69. id: phoneDelegate
    70. Item {
    71. id: wrapper
    72. width: 360
    73. height: 30
    74. MouseArea {
    75. anchors.fill: parent
    76. onClicked: {
    77. wrapper.ListView.view.currentIndex = index
    78. mouse.accepted = true
    79. }
    80. onDoubleClicked: {
    81. wrapper.ListView.view.model.remove(index)
    82. mouse.accepted = true
    83. }
    84. }
    85. RowLayout {
    86. anchors.left: parent.left
    87. anchors.verticalCenter: parent.verticalCenter
    88. spacing: 8
    89. Text {
    90. id: col1
    91. text: name + "\t" + cost + "\t" + manufacturer
    92. color: wrapper.ListView.isCurrentItem ? "red" : "black"
    93. font.pixelSize: wrapper.ListView.isCurrentItem ? 22 : 18
    94. Layout.preferredWidth: 120
    95. }
    96. }
    97. }
    98. }
    99. Component {
    100. id: phoneModel;
    101. ListModel {
    102. ListElement{
    103. name: "iPhone"
    104. cost: "1000"
    105. manufacturer: "Apple"
    106. }
    107. // 省略。。。
    108. }
    109. }
    110. ListView {
    111. id: listView
    112. anchors.fill: parent
    113. delegate: phoneDelegate
    114. model: phoneModel.createObject(listView)
    115. header: headerView
    116. footer: footerView
    117. focus: true
    118. highlight: Rectangle{
    119. color: "lightblue"
    120. }
    121. onCurrentIndexChanged: {
    122. if( listView.currentIndex >=0 ){
    123. var data = listView.model.get(listView.currentIndex)
    124. listView.footerItem.text = data.name + " , " + data.cost + " , " + data.manufacturer
    125. }else{
    126. listView.footerItem.text = ""
    127. }
    128. }
    129. // 2.槽函数:添加数据
    130. function addOne() {
    131. model.append(
    132. {
    133. "name": "MX3",
    134. "cost": "1799",
    135. "manufacturer": "MeiZu"
    136. }
    137. )
    138. }
    139. // 3.连接信号槽
    140. Component.onCompleted: {
    141. listView.footerItem.clean.connect(listView.model.clear)
    142. listView.footerItem.add.connect(listView.addOne)
    143. }
    144. }
    145. }
    146. }

    执行 “qmlscenephone_list_change.qml" 命令后的初始效果如下图所示。

    点击 "Add" 按钮后的效果如下图所示。

    到现在为止,这个例子涵盖了 ListView 的基本应用,包括怎样初始化一个 ListView、访问数据、删除数据、动态添加数据、处理高亮等内容。你可以点击 “Clear” 按钮、点击某个 Item 或者双击某个 Item 看看效果。

  • 相关阅读:
    vue2,3生命周期
    笔记37:全卷积网络FCN结构详解
    【Git1】指令,分支,ssh免密登录
    聊聊 Vue 的双端 diff 算法
    初入编程之门的个人建议1.0
    java计算机毕业设计车辆保险平台系统研究与设计MyBatis+系统+LW文档+源码+调试部署
    MySQL5.7读写分离
    【OpenCV实现图像:OpenCV进行OCR字符分割】
    货币政策传导与货币政策调控-中国视角下的宏观经济
    开源.NetCore通用工具库Xmtool使用连载 - 图形验证码篇
  • 原文地址:https://blog.csdn.net/m0_64560763/article/details/127808130