QT Quick Qml 实例——滑块拖动颜色框的平移(Gradient、drag、clip、transform、antialiasing)

《实例——滑块拖动颜色框的平移》


所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!

QML其它文章请点击这里:     QT QUICK QML 学习笔记


1. 简介

        今天弄了一个实例,如gif所示,当我们拖动滑块的时候,黄绿颜色也会随着拖动而变化。在此中用到了 Gradient颜色渐变、drag实现了滑块、transform的平移、ITem属性的clip,最难处理的是,当长宽变化后,如何去保持滑块和颜色比列不变(小菜鸟的自以为)
在这里插入图片描述
( 说个题外话,CSDN不方便传视频,但可以转gif再传,这个MP4转GIF的在线网站超好用

2. 详解

        共有两个QML文件,一个是主文件SliderMain.qml,它实例化了另外一个颜色变化的ColorRect.qml,且实现了滑块的逻辑。SliderMain.qml如下:

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    property int _pix: 16
    property int _margin: 10
    property real _defaultSilderValue
    property int oldHeight: container.height;
    width: 300; height: 300
    visible: true;

    Rectangle {
        anchors.fill: parent;
        color: "lightGray"

		//1、 实例化了ColorRect.qml文件,且传入了要平移的value。
        ColorRect {
            id: colorRect
            anchors.centerIn: parent
            //[重点1]: 因为需要小滑块处于正中间,且正中间的值为0
            value :   slider.y - _defaultSilderValue;
        }

        //2、 滑块条的实现
        Rectangle {
            id: container
            anchors {
                top: parent.top;
                topMargin: _margin * 2;
                bottom: parent.bottom;
                bottomMargin: _margin *2;
                right: parent.right;
                rightMargin: _margin
            }
            width: _pix
            radius: width/2;
            opacity: 0.6            //不透明度
            antialiasing: true      // 抗锯齿,具体效果见下面图片
            //黑色——>棕色的渐变
            gradient: Gradient {
                GradientStop { position: 0.0; color: "black" }
                GradientStop { position: 1.0; color: "brown" }
            }

            //[重点2]:当面板放大放小的时候,需要保持滑块的比例不变
            onHeightChanged: {
                if(height <= slider.height){     //当缩小的太小的时候,可以把小滑块也跟着变小
                    slider.height = height;      //小滑块高度  =  滑道高度
                }
                else  {
                    slider.height = _pix*2;      //小滑块高度  =  固定高度
                    var _scale =  (height -  _pix*2) / (oldHeight -  _pix*2) 
                    //比列尺 * 之前的实际距离
                    slider.y =  slider.y * _scale;
                    oldHeight = height;
                    //[重点3]默认中间值,也会随着长宽拖动而变化的。
                    _defaultSilderValue = height/2-_pix;
                }
            }
            //小滑块条
            Rectangle {
                id: slider
                x: 1; y: container.height/2-_pix;    //y轴向向下为负, 默认滑块放中间
                width: _pix-2;  height: _pix*2  ;
                radius: width/2;
                antialiasing: true
                gradient: Gradient {
                    GradientStop { position: 0.0; color: "green" }
                    GradientStop { position: 1.0; color: "aqua" }
                }
                MouseArea {
                    anchors.fill: parent
                    anchors.margins: -_pix
                    drag.target: parent;
                    drag.axis: Drag.YAxis
                    drag.minimumY: 1;
                    drag.maximumY: container.height - slider.height-1;
                }
            }
        }
    }
}

        具体的解释,看注释就好了,重要的部分用 “[重点x]” 标记了,注释直接加在代码上才更香嘛。下面是ColorRect.qml 颜色文件的实现:

import QtQuick 2.3

Item {
    property real value;

    id: root
    //[重点1]:clip, 当元素的子项超出父项范围后会自动裁剪,也就是子项超出了范围就剪切掉,不让他显示和起作用
    //在此中,限定在距离parent的54的范围内,默认为false
    clip:           true
    anchors.fill:   parent
    anchors.margins: 54;

    Item {
        width:  root.width
        height: root.height * 3; //高一点,不然上下颜色会被移没去...
        anchors.centerIn: parent
        Rectangle {
            id: _top
            anchors.fill: parent
            smooth: true
            antialiasing: true
            gradient: Gradient {
                GradientStop { position: 0; color: "green" }
                GradientStop { position: 0.5;  color: "aqua" }
            }
        }
        Rectangle {
            id: _bottom
            height: _top.height / 2
            anchors {
                left:   _top.left;
                right:  _top.right;
                bottom: _top.bottom
            }
            smooth: true
            antialiasing: true
            gradient: Gradient {
                GradientStop { position: 0.0;  color: "yellow"  }
                GradientStop { position: 1; color: "orange" }
            }
        }
        //蓝绿面板的上下平移
        transform: Translate{
            y:  value         //Y轴方向的偏移量
        }
    }
}

恩,就只有这两个文件,参考了下官网的实例,QT Creat 欢迎中搜“dial control”,它是拖动滑块实现了仪表盘的旋转。
在这里插入图片描述
它的演示如下
在这里插入图片描述
核心代码代码在此,transform的对象是Rotation ,并对角度设计了个弹簧动画,之前已经学过了弹簧动画了QT Quick QML 动画——SpringAnimation弹簧动画和Behavior

Image {
     id: needle
     x: 98; y: 33
     antialiasing: true
     source: "needle.png"
     transform: Rotation {
         id: needleRotation
         origin.x: 5; origin.y: 65
         //! [needle angle]
         angle: Math.min(Math.max(-130, root.value*2.6 - 130), 133)
         Behavior on angle {
             SpringAnimation {
                 spring: 1.4
                 damping: .15
             }
         }
         //! [needle angle]
     }
 }

● 抗锯齿(antialiasing)
        再补充下抗锯齿的表现,开了抗锯齿,效果明显,可能性能下降吧,但是小程序在乎这点性能吗,建议开启。左图是开启了抗锯齿。
在这里插入图片描述


QML其它文章请点击这里:     QT QUICK QML 学习笔记

  • 39
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现QMLDrag和Drop模式同样的操作,可以使用Qt中的QDrag和QDropEvent类来处理。具体步骤如下: 1. 在源控件(B控件)中,实现mousePressEvent和mouseMoveEvent事件,用QDrag创建一个拖动对象,并将其MIME数据设置为要传递的数据。 2. 在目标控件(A控件)中,实现dragEnterEvent、dragMoveEvent和dropEvent事件。在dragEnterEvent和dragMoveEvent事件中,使用QDropEvent的acceptProposedAction方法接受拖动操作。在dropEvent事件中,使用QDropEvent的mimeData方法获取传递的数据。 以下是C++代码示例: 在源控件(B控件)中: ``` void MyWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; // 设置MIME数据 mimeData->setText("Hello World"); drag->setMimeData(mimeData); drag->exec(Qt::CopyAction); } } void MyWidget::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) { // 开始拖动操作 QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; // 设置MIME数据 mimeData->setText("Hello World"); drag->setMimeData(mimeData); drag->exec(Qt::CopyAction); } } ``` 在目标控件(A控件)中: ``` void MyWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); } } void MyWidget::dragMoveEvent(QDragMoveEvent *event) { if (event->mimeData()->hasText()) { event->acceptProposedAction(); } } void MyWidget::dropEvent(QDropEvent *event) { if (event->mimeData()->hasText()) { QString text = event->mimeData()->text(); // 处理传递的数据 event->acceptProposedAction(); } } ``` 以上就是在C++中实现QMLDrag和Drop模式同样的操作的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值