qml基础学习 模型视图(一)

2023-11-12

一、理解qml模型和视图

qt的发展是迅速的,虽然在每一个release版本中或多或少都有bug,但是作为一个庞大的gui库,no,应该说是一个开发框架开说,qt已经算是做的相当好。qml部分是qt4.7的时候推出的,当时qml只是为了移动端而设计的开发语言,随着it行业的发展,桌面端也产生了一定的需求,这就使得qml也必须支持桌面端的开发。使用qml可以做出绚丽的界面,并把逻辑和界面展示分开,qml和C++就好比html和JavaScript。

qt中有大量的model/view类,视图类:QTableView、QListView和QTreeView,模型类:QAbstractTableModel、QAbstractListModel和QAbstractProxyModel,这三个模型类都是继承自QAbstractItemModel。对于qml语言来说,也有model和view,他们分别就是GridView、ListView和PathView,其中GridView和ListView在qt中都有对于的实现类,PathView是最难理解的view,也是最灵活的view,他可以做出各种各样比较绚丽的效果。

二、效果展示

这一节我们主要是说明qml中的视图类,如下效果图展示的那样,图1是用GridView实现,图2是用ListView实现,view的item项都是用代理进行绘制;图3是用PathView实现的一个效果图,类似于一个卡牌弹出弹入效果。

顺道提一嘴,qml文件都是可以使用qmlscene.exe来预览

三、源码分析

每一个示例中都有大量的注释,具体细节可以参看注释

1、GridView增删

如图1所示,这是一个GridView的简单示例,示例完成单击Add Item按钮实现新增项,点击项实现删除等功能。

import QtQuick 2.0

Rectangle {
    width: 480;
    height: 300;

    //背景色渐变
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#dbddde"; }
        GradientStop { position: 1.0; color: "#5fc9f8"; }
    }

    //list模型默认9项
    ListModel {
        id: theModel

        ListElement { number: 0; }
        ListElement { number: 1; }
        ListElement { number: 2; }
        ListElement { number: 3; }
        ListElement { number: 4; }
        ListElement { number: 5; }
        ListElement { number: 6; }
        ListElement { number: 7; }
        ListElement { number: 8; }
        ListElement { number: 9; }
    }

    //Add Item按钮
    Rectangle {
        anchors.left: parent.left;
        anchors.right: parent.right;
        anchors.bottom: parent.bottom;
        anchors.margins: 20;

        height: 40;

        color: "#53d769";
        border.color: Qt.lighter(color, 1.1);

        Text {
            anchors.centerIn: parent;

            text: "Add item!";
        }

        //点击时新增项  实现model的动态新增
        MouseArea {
            anchors.fill: parent;

            onClicked: {
                theModel.append({"number": ++parent.count});
            }
        }

        property int count: 9;//
    }

    GridView {
        anchors.fill: parent;
        anchors.margins: 20;
        anchors.bottomMargin: 80;

        clip: true;

        model: theModel;//绑定数据源

        cellWidth: 45;//设置项大小
        cellHeight: 45;

        delegate: numberDelegate;//设置绘制代理
    }

    //自定义绘制代理
    Component {
        id: numberDelegate;

        Rectangle {
            id: wrapper;

            width: 40;
            height: 40;

            //首先是一个渐变的矩形框
            gradient: Gradient {
                GradientStop { position: 0.0; color: "#f8306a"; }
                GradientStop { position: 1.0; color: "#fb5b40"; }
            }

            //文本值是number的数值
            Text {
                anchors.centerIn: parent;

                font.pixelSize: 10;

                text: number;
            }

            //鼠标点击代理时,移除点击项
            MouseArea {
                anchors.fill: parent;

                onClicked: {
                    if (!wrapper.GridView.delayRemove)//是否延迟移除
                    {
                        theModel.remove(index);
                    }
                }
            }

            //GridView移除项  顺序动画
            GridView.onRemove: SequentialAnimation {
                //属性变化
                PropertyAction {
                    target: wrapper;
                    property: "GridView.delayRemove";
                    value: true;
                }
                //数字动画
                NumberAnimation {
                    target: wrapper;//目标对象
                    property: "scale";//执行动画的属性
                    to: 0;//结束值
                    duration: 250;//动画持续时长
                    easing.type: Easing.InOutQuad;//动画执行曲线
                }
                PropertyAction {
                    target: wrapper;
                    property: "GridView.delayRemove";
                    value: false;
                }
            }

            //GridView新增项  顺序动画
            GridView.onAdd: SequentialAnimation {
                NumberAnimation {
                    target: wrapper;
                    property: "scale";
                    from: 0;//开始值
                    to: 1;
                    duration: 250;
                    easing.type: Easing.InOutQuad;
                }
            }
        }
    }
}

2、列表

如图2所示,是一个使用ListView实现的列表控件,点击列表控件中的项,可以实现最大化来展示列表的详细信息

import QtQuick 2.0

Item {
    width: 300;
    height: 480;

    //渐变别景色
    Rectangle {
        anchors.fill: parent;
        gradient: Gradient {
            GradientStop { position: 0.0; color: "#4a4a4a"; }
            GradientStop { position: 1.0; color: "#2b2b2b"; }
        }
    }

    //主界面列表视图
    ListView {
        id: listView;

        anchors.fill: parent;

        delegate: detailsDelegate;//设置绘制代理
        model: planets;//绑定数据源
    }

    ListModel {
        id: planets;

        ListElement {
            name: "Mercury";
            imageSource: "images/mercury.jpeg";
            facts: "Mercury is the smallest planet in the Solar System. It is the closest planet to the sun. It makes one trip around the Sun once every 87.969 days." ;
        }
        ListElement {
            name: "Venus";
            imageSource: "images/venus.jpeg";
            facts: "Venus is the second planet from the Sun. It is a terrestrial planet because it has a solid, rocky surface. The other terrestrial planets are Mercury, Earth and Mars. Astronomers have known Venus for thousands of years.";
        }
        ListElement {
            name: "Earth";
            imageSource: "images/earth.jpeg";
            facts: "The Earth is the third planet from the Sun. It is one of the four terrestrial planets in our Solar System. This means most of its mass is solid. The other three are Mercury, Venus and Mars. The Earth is also called the Blue Planet, 'Planet Earth', and 'Terra'.";
        }
        ListElement {
            name: "Mars";
            imageSource: "images/mars.jpeg";
            facts: "Mars is the fourth planet from the Sun in the Solar System. Mars is dry, rocky and cold. It is home to the largest volcano in the Solar System. Mars is named after the mythological Roman god of war because it is a red planet, which signifies the colour of blood.";
        }
    }

    Component {
        id: detailsDelegate;

        Item {
            id: wrapper;

            width: listView.width;
            height: 30;

            //列表项文本
            Rectangle {
                anchors.left: parent.left;
                anchors.right: parent.right;
                anchors.top: parent.top;

                height: 30;

                color: "#333";
                border.color: Qt.lighter(color, 1.2);
                Text {
                    anchors.left: parent.left;
                    anchors.verticalCenter: parent.verticalCenter;
                    anchors.leftMargin: 4;

                    font.pixelSize: parent.height-4;
                    color: '#fff';

                    text: name;//ListElement中的name
                }
            }

            //列表项图标
            Rectangle {
                id: image;

                width: 26;
                height: 26;

                anchors.right: parent.right;
                anchors.top: parent.top;
                anchors.rightMargin: 2;
                anchors.topMargin: 2;

                color: "yellow";

                Image {
                    anchors.fill: parent;

                    fillMode: Image.PreserveAspectFit;

                    source: imageSource;//ListElement中的imageSource
                }
            }

            //鼠标点击列表项 进行状态前切换,
            MouseArea {
                anchors.fill: parent;
                onClicked: parent.state = "expanded";//切换到展开状态
            }

            //详情页展开时,文本详细信息
            Item {
                id: factsView;

                anchors.top: image.bottom;//位于放大后的图标底部
                anchors.left: parent.left;
                anchors.right: parent.right;
                anchors.bottom: parent.bottom;

                opacity: 0;//默认透明不显示  当点击代理项时该属性会慢慢变得可见

                Rectangle {
                    anchors.fill: parent;

                    gradient: Gradient {
                        GradientStop { position: 0.0; color: "#fed958"; }
                        GradientStop { position: 1.0; color: "#fecc2f"; }
                    }
                    border.color: '#000000';
                    border.width: 2;

                    Text {
                        anchors.fill: parent;
                        anchors.margins: 5;

                        clip: true;//可剪切
                        wrapMode: Text.WordWrap;//文本支持换行
                        color: '#1f1f21';

                        font.pixelSize: 12;

                        text: facts;
                    }
                }
            }

            //项最大化时 右上角关闭按钮
            Rectangle {
                id: closeButton;

                anchors.right: parent.right;
                anchors.top: parent.top;
                anchors.rightMargin: 2;
                anchors.topMargin: 2;

                width: 26;
                height: 26;

                color: "#157efb";
                border.color: Qt.lighter(color, 1.1);

                opacity: 0;

                MouseArea {
                    anchors.fill: parent;
                    onClicked: wrapper.state = "";//点击恢复到默认状态
                }
            }

            //自定义代理状态
            states: [
                State {
                    name: "expanded";
                    //在点击列表项后 各项属相变化

                    //代理高度铺满视图高度
                    PropertyChanges { target: wrapper; height: listView.height; }
                    //列表项的图标放大
                    PropertyChanges {
                        target: image;
                        width: listView.width;
                        height: listView.width;
                        anchors.rightMargin: 0;
                        anchors.topMargin: 30//距离顶部30像素
                    }
                    //文本详细信息可见
                    PropertyChanges { target: factsView; opacity: 1; }
                    //关闭按钮可见
                    PropertyChanges { target: closeButton; opacity: 1; }
                    //列表项视图
                    PropertyChanges {
                        target: wrapper.ListView.view;
                        contentY: wrapper.y;
                        interactive: false
                    }
                }
            ]

            //项变化时 过程
            transitions: [
                Transition {
                    NumberAnimation {
                        duration: 200;
                        properties: "height,width,anchors.rightMargin,anchors.topMargin,opacity,contentY";
                    }
                }
            ]
        }
    }
}

3、卡牌效果

示例代码可以直接放在qml文件中使用qmlscene.exe来预览

import QtQuick 2.6

Rectangle {
    id: root;
    width: 480;
    height: 300;

    PathView
    {
        anchors.fill: parent;

        delegate: flipCardDelegate;
        model: 100;

        path: Path{
            startX: root.width / 2;
            startY: 0

            PathAttribute { name: "itemAngle"; value: -45.0; }
            PathAttribute { name: "itemScale"; value: 0.5; }
            PathAttribute { name: "itemZ"; value: 0; }//属性值附加到代理上面
            PathLine { x: root.width/2; y: root.height*0.4; }//路径元素定义
            PathPercent { value: 0.48; }//控制两个元素之间的路径所占百分比
            PathLine { x: root.width/2; y: root.height*0.5; }
            PathAttribute { name: "itemAngle"; value: 0.0; }
            PathAttribute { name: "itemScale"; value: 1.0; }
            PathAttribute { name: "itemZ"; value: 100 }
            PathLine { x: root.width/2; y: root.height*0.6; }
            PathPercent { value: 0.52; }
            PathLine { x: root.width/2; y: root.height; }
            PathAttribute { name: "itemAngle"; value: 45.0; }
            PathAttribute { name: "itemScale"; value: 0.5; }
            PathAttribute { name: "itemZ"; value: 0; }
        }

        pathItemCount: 17;//可见元素数目

        preferredHighlightBegin: 0.5;
        preferredHighlightEnd: 0.5;
    }
    Component{
        id: flipCardDelegate;

        Rectangle{
            id: wrapper;

            width: 64;
            height: 64;
            antialiasing: true;//反锯齿

            //代理背景色渐变
            gradient: Gradient{
                GradientStop { position: 0.0; color: "#2ed5fa"; }
                GradientStop { position: 1.0; color: "#2467ec"; }
            }

            visible: PathView.onPath;//在PathView上的项可见,不在视图上的项不可见

            scale: PathView.itemScale;//缩放
            z: PathView.itemZ;//z值  数值大的在上面

            property variant rotX: PathView.itemAngle;//属性别名 主要是因为要在底下这个旋转过程中使用

            //动画过程旋转
            transform: Rotation {
                axis { x: 1; y: 1; z: 1; }//绕x轴旋转
                angle: wrapper.rotX;//旋转角度
                origin { x: 32; y: 32; }//旋转基点
            }
            Text{
                anchors.horizontalCenter: parent.horizontalCenter;
                anchors.verticalCenter: parent.verticalCenter;
                text: index;
            }
        }
    }
}

四、相关文章

qml基础学习(一) 基础概念


如果您觉得文章不错,不妨给个 打赏,写作不易,感谢各位的支持。您的支持是我最大的动力,谢谢!!!




很重要–转载声明

  1. 本站文章无特别说明,皆为原创,版权所有,转载时请用链接的方式,给出原文出处。同时写上原作者:朝十晚八 or Twowords

  2. 如要转载,请原文转载,如在转载时修改本文,请事先告知,谢绝在转载时通过修改本文达到有利于转载者的目的。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qml基础学习 模型视图(一) 的相关文章

随机推荐

  • 闲谈开闭原则——基于UI动画框架

    本文继续聊另外一个设计原则 开闭原则 在UI动画框架中 开闭原则在 动画策略 和 移动算法 这两个类体系中均有所体现 照旧 先看一下开闭原则的定义 1 开闭原则 一个软件实体如类 模块和函数应该对扩展开放 对修改关闭 有人说过 唯一不变的就
  • No artifacts marked for deployment 解决方法(ideaweb项目配置tomcat步骤)

    No artifacts marked for deployment 出现这种情况的原因 创建新项目的时候要先添加freework support 步骤如下 添加完成后点击添加tomcat的位置 有main的情况也不影响 接下来按下面步骤就
  • 【airtest架构】pytest+pocoui+airtest+allure 完成安卓UI自动化框架

    一 背景 为了做app的自动化 由于app元素定位麻烦或者定位不稳定 又或者使用驱动版本等原因 不想使用启动appnium服务的方式 本文采用网易的airtest框架图像识别作为基础 配合pytest进行简单的二次开发形成一套对安卓app
  • 操作系统内存管理4.21

    离散内存管理方案 为了提高内存的利用率 缺点 访问效率下降 分页式内存管理方案 现代操作系统常用方案 分段式内存管理方案 段页式内存管理方案
  • 【Vue】/deep/、>>>、v::deep 三种深度选择器

    在 Vue项目中 当一个组件使用了 scoped 特性时 组件内的样式只会应用于组件自身 但是有时候我们需要在 父组件中改变子组件中的样式 这时就需要用到深度选择器 一 deep 二 gt gt gt search input gt gt
  • uni-app 使用Weex/nvue的注意事项

    介绍 uni app App端内置了一个基于 weex 改进的原生渲染引擎 提供了原生渲染能力 在App端 如果使用vue页面 则使用webview渲染 如果使用nvue页面 native vue的缩写 则使用原生渲染 一个App中可以同时
  • java 日历 获取月份_使用Java日历获取月份和年份的星期

    要使用Calendar类 请导入以下程序包 import java util Calendar 创建一个Calendar类对象 Calendar cal Calendar getInstance 现在 使用以下字段获取月份和年份的星期 Ca
  • 浅析:Spring框架中IOC容器和Bean的配置

    一 IOC和DI的解释 1 IOC Inversion of Control 反转控制 在应用程序中的组件需要获取资源时 传统的方式是组件主动的从容器中获取所需要的资源 在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式 增加
  • 深度学习在情感分类中的应用

    简介与背景 情感分类及其作用 情感分类是情感分析的重要组成部分 情感分类是针对文本的情感倾向进行极性分类 分类数量可以是二分类 积极或消极 也可以是多分类 按情感表达的不同程度 情感分析在影音评论 商品评价 舆情分析 股民基金情感分析等都有
  • csgo显示服务器ip,CSGO所有服务器IP段/地理位置

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 SDR服务器IP段 atl addresses 162 254 199 170 27015 27050 162 254 199 171 27015 27050 ams addresses 155
  • 【构建ML驱动的应用程序】第 7 章 :使用分类器编写推荐

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 【C++/STL】手撕红黑树

    文章目录 1 红黑树的概念 1 1红黑树的性质和规则 2 红黑树的模拟实现 2 1节点的定义 2 2节点的插入 1 情况一 u存在且为红色 2 情况二 u不存在 u存在且为黑 并且g p cur为一条直线 3 情况三 u不存在 u存在且为黑
  • Ansible基础3——playbook

    文章目录 一 基本了解 二 编写playbook 2 1 单剧本 2 2 多剧本 2 3 特权升级 2 4 语法优化 三 模块查找 一 基本了解 为什么要写playbook 前面我们可以使用临时命令对受控机进行操作 但当有重复性的工作时就不
  • 自定义带参数二维码扫码进入微信小程序获取参数

    第一步 需要进入小程序后台 开发设置里 添加二维码规则 第二步 添加好扫码进入的规则 比如扫码进去小程序的指定页面 1 协议类型选择https 2 选择小写 3 二维码规则 这个看文档有些人估计会比较迷糊 简单理解一下就是一个https的路
  • 后台@RequestBody接收对象List属性为null

    后台 RequestBody接收对象List属性为null 前端把一个本应传String类型的属性 传成了List数组 会导致后面的所有List属性都会变成null
  • C语言扫雷解析

    目录 扫雷功能说明 游戏界面 游戏分析设计 数据结构的分析 文件结构设计 扫雷游戏代码的实现 game h game c 初始化数组 打印棋盘 布置雷 统计周围雷的个数 排查结果判定 test c 扫雷功能说明 使用控制台实现经典的扫雷游戏
  • php模块化供前端ajax调用的实现

    背景 没有使用php框架 由于临时需求 需要ajax调用php中的方法 简单的写了一个php文件 文件定义了两个方法 如何用ajax分别调用同一个php文件不同的方法 以下是abc php文件 我定义的两个方法a方法和b方法
  • 发现了uroport工具的一个bug,还不知道如何解决

    点击条件属性下的 配置条件 进行配置的 让一个属性等于0的时候控制样式 预览 保存一切正常 等到下次打开这个文件的时候 表示等于的双等号 变成了undefined 如下图 这时候点保存 或者预览 都也点不了 但是不耽误使用 也可以一个一个将
  • Springboot2整合阿里云OSS实现文件上传、下载、删除、查看

    1 阿里云配置 https jingyan baidu com article ea24bc3973db059a63b3316d html 2 pom文件
  • qml基础学习 模型视图(一)

    文章目录 一 理解qml模型和视图 二 效果展示 三 源码分析 1 GridView增删 2 列表 3 卡牌效果 四 相关文章 一 理解qml模型和视图 qt的发展是迅速的 虽然在每一个release版本中或多或少都有bug 但是作为一个庞