QML自定义可长按短按的SpinBox

默认长按+10.短按+1
在这里插入图片描述
主要难点在区分长按和短按,以1s为界限.这里我使用了四个定时器用于实现加和减的长短按操作.

shortClickTimer定时器用来在鼠标松开的时候判断是否是短按:
如果是短按的话我们需要借助forbidClickTimer定时器短暂禁用Click事件,否则会出现长按松开的时候+10后又+1的情况.
如果不是短按的话需要停止longPressminuxTimer/longPressminuxTimer定时器,这两个定时器如果没有被停止,将会在1s后执行+10/-10的操作(也就是长按后每秒产生的效果).

变量说明:
iStepSize短按的步进
iStartValue最小值
iEndValue最大值
iValue当前值
iLongStepSize长按的步进

import QtQuick 2.2
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0

Rectangle{
    id:playbackBox
    property int iStepSize: 1
    property int iStartValue: 1
    property int iEndValue: 200
    property int iValue: 1
    property int iLongStepSize: 10
    width: 300
    height:50
    //显示框
    Rectangle{
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.left: minusBtn.right
        anchors.right: addBtn.left
        border.color: "#CCCCCC"
        border.width: 1
        Text{
            anchors.fill: parent
            text:String(iValue)
            font.pixelSize: 30
            font.weight: Font.Bold
            color: "black"
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
        }
    }
    //+按钮
    Rectangle{
        id:addBtn
        anchors.right: parent.right
        width: parent.height
        height: parent.height
        border.color: "#CCCCCC"
        border.width: 1
        Canvas {
            id:addImg
            anchors.fill: parent
            onPaint: {
                var ctx = getContext("2d")
                //画+
                var x = parent.height / 3;
                var y = parent.height / 2;
                ctx.beginPath()
                ctx.strokeStyle = "rgb(0, 0, 0)";
                ctx.lineWidth = 3
                ctx.moveTo(x, y);
                ctx.lineTo(addImg.width - x, y)
                x = parent.height / 2;
                y = parent.height / 3;
                ctx.moveTo(x, y);
                ctx.lineTo(x, addImg.width - y)
                ctx.stroke()
            }
        }
        //长按+10, 以及规避长按松开后触发onClicked导致再+1问题
        MouseArea{
            anchors.fill: parent
            onPressed: {
                if(!shortClickTimer.running)
                {
                    shortClickTimer.start()
                }

                if(!longPressAddTimer.running)
                {
                    longPressAddTimer.start();
                }
                addBtn.color = "#f0f0f0";
            }
            onReleased: {
                if(!shortClickTimer.running)
                {
                    forbidClickTimer.start();
                }
                longPressAddTimer.stop();
                addBtn.color = "#ffffff";
            }
            onClicked: {
                if(forbidClickTimer.running)
                {
                    return;
                }
                if(iValue >= iEndValue)
                {
                    return;
                }
                iValue += iStepSize;
            }
        }
        Timer{
            id:longPressAddTimer
            running: false
            repeat: true
            interval: 1000
            onTriggered: {
                if(iValue + iLongStepSize > iEndValue)
                {
                    iValue = iEndValue;
                }
                else
                {
                    iValue += iLongStepSize;
                }
            }
        }
    }
    Rectangle{
        id:minusBtn
        anchors.left: parent.left
        width: parent.height
        height: parent.height
        border.color: "#CCCCCC"
        border.width: 1
        Canvas {
            id:minImg
            anchors.fill: parent
            onPaint: {
                var ctx = getContext("2d")
                //画-
                var x = parent.height / 3;
                var y = parent.height / 2;
                ctx.beginPath()
                ctx.strokeStyle = "rgb(0, 0, 0)";
                ctx.lineWidth = 3
                ctx.moveTo(x, y);
                ctx.lineTo(minImg.width - x, y)
                ctx.stroke()
            }
        }
        MouseArea{
            anchors.fill: parent
            onPressed: {
                if(!shortClickTimer.running)
                {
                    shortClickTimer.start()
                }
                if(!longPressminuxTimer.running)
                {
                    longPressminuxTimer.start();
                }
                minusBtn.color = "#f0f0f0";
            }
            onReleased: {
                if(!shortClickTimer.running)
                {
                    forbidClickTimer.start();
                }
                longPressminuxTimer.stop();
                minusBtn.color = "#ffffff";
            }
            onClicked: {
                if(forbidClickTimer.running)
                {
                    return;
                }
                if(iValue <= iStartValue)
                {
                    return;
                }
                iValue -= iStepSize;
            }
        }
        Timer{
            id:longPressminuxTimer
            running: false
            repeat: true
            interval: 1000
            onTriggered: {
                if(iValue - iLongStepSize < iStartValue)
                {
                    iValue = iStartValue;
                }
                else
                {
                    iValue -= iLongStepSize;
                }
            }
        }
        //长按松开后不触发点击事件
        Timer{
            id:forbidClickTimer
            running: false
            repeat: false
            interval: 20
        }
        Timer{
            id:shortClickTimer
            running: false
            repeat: false
            interval: 999
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值