首页 > 其他分享 >Qt Quick 消息列表视图组件

Qt Quick 消息列表视图组件

时间:2024-08-21 14:38:28浏览次数:13  
标签:Qt parent 视图 height width Quick property id anchors

目录

开发环境

Qt版本: 6.5.3

构建: cmake + minGW64-bit

简介

这是一个纯QML程序,功能是一个消息列表的功能,可以进行插入,删除,清空等操作

预览图

![2024-08-21 14-28-39_converted](images/2024-08-21 14-28-39_converted.gif)

代码

代码一共分为两个部分,分别为main.qml 和 MessageQueueView.qml

main.qml

展示消息列表组件功能

import QtQuick
import QtQuick.Controls
import QtQuick.Controls.Material

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")

    Item {
        id: root
        width: parent.width
        height: parent.height
        Pane {
            width: parent.width
            height: parent.height
            Column {
                width: 80
                height: 100
                spacing: 10
                Material.theme: Material.System
                Row {
                    Text {
                        text: "插入消息:  "
                    }
                    TextField {
                        Keys.onReturnPressed: {
                            messageQueueView.insert(text,{
                                                     title: "这是一个标题",
                                                     message: "这是第 " + messageQueueView.count +" 条消息"
                                                 })
                        }
                    }
                }
                Row {
                    Text {
                        text: "移除消息:  "
                    }
                    TextField {
                        Keys.onReturnPressed: {
                            messageQueueView.remove(text,1)
                        }
                    }
                }
                Button {
                    text: "清空消息"
                    onClicked: {
                        messageQueueView.clear()
                    }
                    Keys.onReturnPressed: {
                        messageQueueView.model.clear()
                    }
                }
            }
        }

        MessageQueueView {
            id: messageQueueView
            anchors.right: parent.right
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 20
        }
    }
}

MessageQueueView.qml

消息列表组件

// MessageQueueView.qml
import QtQuick
import QtQuick.Controls
Item {
    id: root

    property real margin: 20

    property Component messageItemDelegate: messageDelegate
    property Component background: backgroundCmp

    property alias model: listmodel
    property alias itemsSpacing: listview.spacing
    property alias count: listview.count

    width: 260
    height: 400
    clip: true
    Loader {
        id: backgroundLoader
        anchors.fill: parent
        sourceComponent: root.background
    }
    Component {
        id: backgroundCmp
        Rectangle {
            id: background
            anchors.fill: parent
            color: "#2F000000"
        }
    }


    ListView {
        id: listview
        width: parent.width
        height: parent.height
        spacing: 10
        anchors.horizontalCenter: parent.horizontalCenter
        verticalLayoutDirection: ListView.BottomToTop
        model: ListModel {
            id: listmodel
        }

        delegate: messageItemDelegate
        // add 添加 过渡动画 因add导致被影响的项
        add: Transition {
            id: addTrans
            onRunningChanged: {
                console.log("addTran: " + ViewTransition.item)
            }

            ParallelAnimation {

                NumberAnimation {
                    property: "opacity"
                    from: 0
                    to: 1
                    duration: 300
                    easing.type: Easing.InOutQuad
                }
                PathAnimation {
                    duration: 400
                    easing.type: Easing.InOutQuad
                    path: Path {
                        startX: addTrans.ViewTransition.destination.x + 80
                        startY: addTrans.ViewTransition.destination.y
                        PathCurve {
                            x: (listview.width - addTrans.ViewTransition.item.width) / 2
                            y: addTrans.ViewTransition.destination.y
                        }
                    }
                }
            }


        }
        // add 添加 过渡动画
        addDisplaced: Transition {
            id: dispTran
            onRunningChanged: {
                if(running) {
                    console.log("addDispTran: " + ViewTransition.targetIndexes)
                }
            }
            // 如果数据插入太快会导致动画被中断 然后动画控制的属性值无法回到正确的值,在这里手动回到正确的值
            PropertyAction { property: "opacity"; value: 1;}
            PropertyAction { property: "x"; value: (listview.width - dispTran.ViewTransition.item.width) / 2;}


            NumberAnimation {
                property: "y"
                duration: 300
                easing.type: Easing.InOutQuad
            }

        }

        // remove 移除 过渡动画
        remove: Transition {
            id: removeTran
            onRunningChanged: {
                console.log("removeTran: " + ViewTransition.targetIndexes)
            }
            ParallelAnimation {
                NumberAnimation {
                    property: "x"
                    to: listview.width
                    duration: 500
                    easing.type: Easing.InOutQuart
                }
                NumberAnimation {
                    property: "opacity"
                    from: 1
                    to: 0
                    duration: 400
                    easing.type: Easing.InOutQuart
                }
            }


        }
        // remove 移除 过渡动画 因romove导致被影响的项
        removeDisplaced: Transition {
            id: removeDispTran
            onRunningChanged: {
                console.log("removeDispTran: " + ViewTransition.targetIndexes)
            }
            ParallelAnimation {
                NumberAnimation {
                    property: "y"
                    duration: 500
                    easing.type: Easing.InOutQuart
                }
            }
        }

    }

    Component {
        id: messageDelegate
        Rectangle {
            x: (listview.width - width) / 2
            width: listview.width - root.margin*2
            height: 80
            radius: 8
            color: "#2F000000"
            clip: true
            Row {
                width: parent.width - 20
                height: parent.height - 20
                spacing: 5
                anchors.centerIn: parent
                Image {
                    id: iconImg
                    width: 35
                    height: width
                    anchors.verticalCenter: parent.verticalCenter
                    source: iconSource
                }
                Column {
                    id: infoText
                    width: parent.width - iconImg.width - parent.spacing*2 - toolBar.width
                    height: parent.height
                    spacing: 5
                    Text {
                        property real maxHeight: parent.height * 0.3
                        width: parent.width
                        height: contentHeight
                        wrapMode: Text.Wrap
                        elide: Text.ElideRight
                        font.pointSize: 12
                        font.bold: true
                        text: title
                        color: "#FFFFFF"
                        onContentHeightChanged: (contentHeight) => {
                            if(contentHeight > maxHeight) {
                                height = maxHeight
                            } else {
                                height = contentHeight
                            }
                        }
                    }
                    Text {
                        property real maxHeight: parent.height * 0.7 - parent.spacing
                        width: parent.width
                        height: contentHeight
                        wrapMode: Text.Wrap
                        font.pointSize: 10
                        text: message
                        color: "#FFFFFF"
                        onContentHeightChanged: (contentHeight) => {
                            if(contentHeight > maxHeight) {
                                height = maxHeight
                            } else {
                                height = contentHeight
                            }
                        }
                    }
                }
                Column {
                    id: toolBar
                    width: 15
                    MouseArea {
                        width: parent.width
                        height: width
                        cursorShape: Qt.PointingHandCursor
                        Rectangle {
                            width: parent.width
                            height: 1
                            anchors.centerIn: parent
                            rotation: 45
                        }
                        Rectangle {
                            width: parent.width
                            height: 1
                            anchors.centerIn: parent
                            rotation: -45
                        }
                        onClicked: {
                            remove(index)
                        }
                    }
                }
            }
        }
    }

    function insert(index,info) {
        let title = info.title || "标题"
        let message = info.message || "信息"
        let iconSource = info.iconSource || "qrc:/images/message.svg"
        model.insert(index,{
                        title: title,
                        message: message,
                        iconSource: iconSource
                     })
    }
    function remove(index,count = 1) {
        model.remove(index, count)
    }
    function clear() {
        model.clear()
    }
}

标签:Qt,parent,视图,height,width,Quick,property,id,anchors
From: https://www.cnblogs.com/AutumnEarly/p/18371555

相关文章

  • QT+OpenGL 使用VAO、VBO、EBO结合绘制一个正方形
    一、概述需求:绘制一个正方形,可以控制正方形的颜色、可以切换正方形为线框模式/填充模式绘制流程:1.定义一个顶点着色器和片元着色器shader2.Qt创建一个Widget并继承QOpenGLWidget、QOpenGLFunctions,并重写initializeGL()、resizeGL(w,h)、pai......
  • 数据库:数据更新和视图
    1实验目的(1)掌握SQL语言的数据更新功能:update语句用于对表进行更新delete语句用于对表进行删除    insert语句用于对表进行插入(2)掌握对视图的操作:视图的定义视图的更新    基于视图的查询2实验任务1.将一个新学生元组(学号:95007;姓名:张娜丽;性别:女;所......
  • QT+OpenGL创建一个三角形并动态改变三角形颜色
    一、概述需求:1.使用QT+OpenGL创建一个三角形2.默认三角形为黑色3.可以通过点击按钮改变三角形颜色值(红绿蓝)4.如下图所示ps:这一篇用的是QT封装好的opengl相关帮助类,下一篇会用原生的来写。 二、代码示例1.让......
  • lazarus 编译时切换QT5/GTK2的方法
    lazarus编译时可以随时切换QT5/GTK2,方法如下:在project菜单-->options-->compileroptions-->additionsandoverrides点Set"LCLWidgetType"选择QT5或其他然后重新编译应用就可以。带menu、combobox等控件(在银河麒麟)的应用,用GTK2时有深灰的背景,QT5编译的整体会好点。注意:fastrepor......
  • Qt_ui生成界面原理
    QtUI界面生成原理在使用Qt开发图形用户界面(GUI)时,我们可以使用QtDesigner创建.ui文件,这个文件描述了界面的布局和组件信息。在编译项目时,这些信息会被转换为实际的代码,生成一个可视化的界面。下面是详细的步骤解释:1.创建.ui界面文件本质:.ui文件是一个XML......
  • Qt+ffmpeg环境搭建
    Qt+ffmpeg环境搭建各平台常见视频开发库举例:iOS:AVFoundationAudioUnitAndroid:MediaPlayer,MediaCodecWindows:DirectShowLinux:GStreamerFFmpeg库是一个跨平台的视频开发库,还有libVLC也是一个跨平台的视频开发库掌握了其中一个库,也能很快上手其它库,因为音视频解......
  • QTday4
    思维导图 第二题 widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QTime>#include<QTimerEvent>#include<QTextToSpeech>QT_BEGIN_NAMESPACEnamespaceUi{classWidget;}QT_END_NAMESPACEclassWidget:public......
  • QTabWidget自定义样式(仿DotNetBar)
    QSS如下,若需要tab栏背景色需要添加ui->tabWidget->setAttribute(Qt::WA_StyledBackground);语句使background-color生效,这个时候qtdesigner中仍然看不到背景色,但是不要担心它是生效的,只需在属性中勾上autofillbackground即可在designer中预览(该属性在QWidget属性组中,实际上勾不勾......
  • 【Qt】 对象树 与 乱码问题
    文章目录1.对象树在堆上开辟空间并管理栈上开辟与堆上开辟的区别2.乱码问题的解释编码方式的区分出现乱码的原因查看当前文件的编码方式如何处理文件与终端编码方式不统一1.对象树在堆上开辟空间并管理该代码只进行new(在堆上开辟空间)而没有delete......
  • MQTT
    目录mosquitto搭建本地服务器下载配置启动订阅主题发布消息mosquitto搭建本地服务器下载配置启动mosquitto.exe-cmosquitto.conf-v订阅主题发布消息mosquito_pub-hlocalhost-t"topic"-i"client"-m"message"......