qml拖动交换之Gridview

qml拖动交换之Gridview

    • 坐标变换
    • 代码

QML中mapToItem和mapFromItem的使用

坐标变换

在这里插入图片描述

代码

import QtQuick 2.6
import QtQuick.Window 2.2

Window {
    visible: true
    width: 1024
    height: 480
    title: qsTr("Drag Icon")

    property ListModel dataModel: ListModel {
        ListElement { title: qsTr("电话") }
        ListElement { title: qsTr("相册") }
        ListElement { title: qsTr("短信") }
        ListElement { title: qsTr("网络") }
        ListElement { title: qsTr("微信") }
        ListElement { title: qsTr("设置") }
        ListElement { title: qsTr("日历") }
        ListElement { title: qsTr("天气") }
        ListElement { title: qsTr("百度") }
        ListElement { title: qsTr("时间") }
        ListElement { title: qsTr("生活") }
    }

    QtObject {
        id: d

        readonly property int cellWidth: 128
        readonly property int cellHeight: 128
        readonly property int iconWidth: 96
        readonly property int iconHeight: 96

        property int dragIndex: -1
        property bool dragBehavior: false
    }

    GridView {
        id: gridView
        anchors.fill: parent
        cellWidth: d.cellWidth
        cellHeight: d.cellHeight
        move: Transition {
            NumberAnimation { properties: "x"; duration: 100; easing.type: Easing.OutCubic }
            NumberAnimation { properties: "y"; duration: 100; easing.type: Easing.OutCubic }
        }
        moveDisplaced: Transition {
            NumberAnimation { properties: "x"; duration: 300; easing.type: Easing.OutCubic}
            NumberAnimation { properties: "y"; duration: 100;  easing.type: Easing.OutCubic }
        }
        model: dataModel
        delegate: Item {
            width: d.cellWidth
            height: d.cellHeight
            z: mouseArea.pressed ? 1000 : 1
            Rectangle {
                id: btnIconArea
                anchors.centerIn: parent
                width: d.cellWidth
                height: d.cellWidth
                radius: 8
                border.width: 2
                border.color: "black"
                color:"blue"
                // color: "transparent"
                // border.color: "gray"
                Rectangle {
                    id: btnIcon
                    width: d.iconWidth
                    height: d.iconWidth
                    radius: 8
                    color: "grey"
                    border.color: "black"
                    Behavior on x { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
                    Behavior on y { enabled: d.dragBehavior; NumberAnimation { duration: 200 } }
                    Text {
                        anchors.centerIn: parent
                        color: "white"
                        text: model.title
                    }
                    MouseArea {
                        id: mouseArea
                        anchors.fill: parent
                        drag.target: parent
                        onPressed: {
                            d.dragBehavior = false;
                            var pos = gridView.mapFromItem(btnIcon, 0, 0);
                            console.log("onPressed pos : " + pos);
                            console.log("btnIcon.x: " + btnIcon.x+"btnIcon.y: "+btnIcon.y);
                            d.dragIndex = model.index;
                            btnIcon.parent = gridView;
                            btnIcon.x = pos.x
                            btnIcon.y = pos.y
                        }
                        onReleased: {
                            d.dragIndex = -1;
                            console.log("onReleased btnIcon.x : " + btnIcon.x + "btnIcon.y "+ btnIcon.y);
                            var pos = gridView.mapToItem(btnIconArea, btnIcon.x, btnIcon.y);
                            console.log("onReleased pos : " + pos);
                            console.log("btnIconArea.x: " + btnIconArea.x+"btnIconArea.y: "+btnIconArea.y);
                            // 这里一定要设置parent
                            btnIcon.parent = btnIconArea;
                            // 这几行代码是用来保证动画效果的
                            btnIcon.x = pos.x;
                            btnIcon.y = pos.y;
                            d.dragBehavior = true;
                            btnIcon.x = 0;
                            btnIcon.y = 0;
                        }

                        onPositionChanged: {
                            var pos = gridView.mapFromItem(btnIcon, 0, 0);
                            console.log("onPositionChanged pos :"+pos)
                            var idx = gridView.indexAt(pos.x, pos.y);
                            if (idx > -1 && idx < gridView.count) {
                                dataModel.move(d.dragIndex, idx, 1)
                                d.dragIndex = idx;
                            }

                        }
                    }
                }
            }
        }
    }


    Component.onCompleted: {
        console.log("gridView.spacing = " + gridView.spacing);
    }
}


用上面这个例子举例说明一下,拖动是怎么实现交换的。

我们应该是把A拖到B的时候,A拖到B需要我们自己实现,但是B回到A,或者回到其他地方,GridView会自动帮我们实现?movemoveDisplaced这两个动画需要我们实现。

pressed的时候,会记录当前对象btnIcon的索引dragIndex,同时将这个对象的parent设置为gridview

移动的时候,会不断触发onPositionChanged,将btnIcon对象的左上角坐标,转换成gridview下的坐标,根据这个坐标计算是在gridview中的哪一格,以此来判断是否需要交换。如果需要交换,就将之前记录的那个索引dragIndex对应的元素,移动到新的idx对应的元素那里。也就是说,这个时候,gridview中的元素已经完成了交换。我们拖动的是那个元素里面的一个子元素!

onReleased的时候,首先计算var pos = gridView.mapToItem(btnIconArea, btnIcon.x, btnIcon.y);这是btnIcon在btnIconArea中的相对位置,然后将btnIconparent换成btnIconArea,这一步很重要!!!

d.dragBehavior = true;用来保证动画时间

btnIcon.x = pos.x;
btnIcon.y = pos.y;来保证松开的时候,btnIcon坐标不会偏,然后再设置动画enable,再改变btnIcon坐标,展开一段动画效果。

// 这里一定要设置parent
btnIcon.parent = btnIconArea;
// 这几行代码是用来保证动画效果的
btnIcon.x = pos.x;
btnIcon.y = pos.y;
d.dragBehavior = true;
btnIcon.x = 0;
btnIcon.y = 0;

这里不理解的话,可以自己调试一下,就懂了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/606490.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

摩菲Murphy显示器显示表 总线编程器维修PV780B

Murphy仪器维修包括&#xff1a;摩菲数字显示器&#xff1b;摩菲监视仪表&#xff1b;摩菲CAN总线控制器等维修 维修故障包括&#xff1a;黑屏、指示灯无显示&#xff0c;触摸屏上电无反应&#xff0c; 上电蓝屏、白屏&#xff0c;通电几分钟后屏幕变为蓝屏&#xff0c;主板故…

46. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

android基础-多线程

多线程&#xff1a; 创建子线程&#xff0c;子线程不允许直接更新UI&#xff0c;试想下如果多个线程去更新UI&#xff0c;则会造成资源错乱&#xff0c;如果枷锁就会使得代码冗余复杂。 android异步处理&#xff1a; 另一种异步多线程方法 doInBackground是在子线程中。

VisualGDB:Linux动态库项目创建、编译及库的使用

此篇接上篇 《VisualGDB:为Linux项目添加系统依赖库》,在本篇中我们重点分享一下如何基于VisualGDB 在VS中创建Linux动态库项目,如何编译及使用创建的动态库。 一、VisualGDB创建Linux动态库项目 如下,我们创建一个Linux下的动态库项目MyMath 二、编译动态库 我们稍微…

Baidu Comate:智能编码,编程效率的革新者

文章目录 一、何为智能编码助手&#xff1f;二、Baidu Comate智能编码助手简介三、Baidu Comate注册四、Baidu Comate体验Comate插件功能1.注释生成代码2.函数注释生成3.行间注释生成4.生成代码解释5. 调优建议 五、插件功能的使用体验感受和建议 &#x1f6a9;结语 一、何为智…

【Linux】如何定位客户端程序的问题

文章目录 1 客户端程序和服务端程序的差别2 问题类型2.1 崩溃(crash)2.2 CPU高2.3 内存高2.4 线程卡死 3 总结 1 客户端程序和服务端程序的差别 客户端程序是运行在终端上&#xff0c;通常都会与业务系统共存&#xff0c;而服务端程序通常会运行在单独的节点上&#xff0c;或者…

短信群发平台:全功能SDK短信接口解决方案

SDK短信接口介绍&#xff1a; 为了满足不同企业的需求&#xff0c;我们提供了一站式SDK短信接口解决方案。这些接口不仅功能强大&#xff0c;而且易于集成到现有的企业系统中&#xff0c;以提供更加安全、高效和便捷的服务。 1.短信验证码接口&#xff1a;用于用户注册、密码修…

PY计算生态是什么?

Python 的计算生态指的是与 Python 相关的广泛的软件、库、框架和工具集合. 它们为各种计算任务提供了丰富的解决方案和支持。Python 作为一种简洁、易学、功能强大的编程语言&#xff0c;在科学计算、数据分析、人工智能、机器学习等领域都有着强大的影响力。以下是 Python 计…

深度学习之视觉特征提取器——GoogleNet/Inception

GoogleNet GoogleNet在2014年中的ImageNet夺冠&#xff0c;将Inception这一结构推向了热潮。从另外一个角度来看&#xff0c;CV魔改网络结构也从中得到启发或者说推动&#xff0c;拓宽了各种魔改的方式。GoogleNet其实只是Inception这一结构大规模集成后得到的模型&#xff0c…

自建WSUS更新服务器完成内网的安全补丁更新

一、适用场景 1、企业内部网络无法访问外网&#xff0c;所以搭建WSUS服务器&#xff0c;可以让内网环境进行更新补丁。 2、校园内部的电脑实训室一般不用外网资源&#xff0c;偶尔开启外网使用时&#xff0c;电脑实训室集体自动更新占用外网资源量大&#xff0c;所以搭建WSUS服…

云动态摘要 2024-05-08

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]即刻畅享自研SaaS产品 腾讯云 2024-04-25 涵盖办公协同、营销拓客、上云安全保障、数据分析处理等多场景 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用…

JavaEE 初阶篇-深入了解 HTTP 协议

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 HTTP 协议概述 2.0 HTTP 请求协议 2.1 请求方式的具体体现 3.0 HTTP 响应协议 3.1 常见的状态码及描述 3.2 常见的响应头 4.0 HTTP 协议解析 4.1 简单实现服务器响…

Linux/Intuition

Intuition Enumeration nmap 使用 nmap 扫描系统常见端口&#xff0c;发现对外开放了 22 和 80&#xff0c;然后扫描这两个端口的详细信息 ┌──(kali㉿kali)-[~/vegetable/HTB/Intuition] └─$ nmap -sC -sV -p 22,80 -oA nmap 10.10.11.15 Starting Nmap 7.93 ( https:…

Springboot+vue项目影城管理系统

摘 要 本论文主要论述了如何使用JAVA语言开发一个影城管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述影城管理系统的当前背景以及系统开发的目的&…

计算机SCI期刊,IF=9.657,1区TOP,2周内出版!

一、期刊名称 Neural Networks 二、期刊简介概况 期刊类型&#xff1a;SCI 学科领域&#xff1a;计算机科学 影响因子&#xff1a;7.8 中科院分区&#xff1a;1区TOP 出版方式&#xff1a;订阅模式/开放出版 版面费&#xff1a;选择开放出版需支付$3350 三、期刊简介 神…

Shell生成支持x264的ffmpeg安卓全平台so

安卓 FFmpeg系列 第一章 Ubuntu生成ffmpeg安卓全平台so 第二章 Windows生成ffmpeg安卓全平台so 第三章 生成支持x264的ffmpeg安卓全平台so&#xff08;本章&#xff09; 文章目录 安卓 FFmpeg系列前言一、实现步骤1、下载x264源码2、交叉编译生成.a3、加入x264配置4、编译ffmp…

【ZIP技巧】ZIP分卷压缩包如何解压?

经过压缩的文件仍然过大&#xff0c;大家可能都会选择“分卷压缩”来压缩ZIP文件&#xff0c;但是当我们将压缩包分卷之后&#xff0c;解压的时候该如何解压&#xff1f;今天我们分享两个ZIP分卷压缩包如何解压的方法给大家。 一、 我们可以直接点击第一个分卷压缩包&#xf…

DHC:用于类别不平衡的半监督医学图像分割的双重去偏异构协同框架

文章目录 DHC: Dual-Debiased Heterogeneous Co-training Framework for Class-Imbalanced Semi-supervised Medical Image Segmentation摘要方法Distribution-aware Debiased Weighting (DistDW)Difficulty-aware Debiased Weighting (DiffDW) 实验结果 DHC: Dual-Debiased He…

Context capture/Pix4Dmapper/AutoCAD/CASS/EPS软件的安装流程与使用方法;土方量计算;无人机摄影测量数据处理

目录 专题一 无人机摄影测量技术应用现状及其发展 专题二 基本原理和关键技术讲解 专题三 无人机影像外业数据获取 专题四 数据处理环境建立与软件熟悉 专题五 GNSS数据土方量计算 专题六 基于无人机影像数据的正射影像制作 专题七 基于无人机影像数据的三维模型制作 专…

TS流加扰的判断

一般情况下&#xff0c;1套节目是否加扰 在SDT表中或者包头的加扰位2处判断。 1.SDT表的free_CA_mode0是未加密&#xff0c;1是加密&#xff1b;在SDT表中&#xff0c;只是一个规范&#xff08;如果节目加密了&#xff0c;应该让free_CA_mode1&#xff09;。实际上&#xff0c…