qml: 自定义滚动条;

注:  该博文为原创博文,转载请注明,摘用请随意;

qml自带的滚动条不太好用;

首先,利用canvas绘制滚动条两端的箭头:

import QtQuick 2.0

Canvas {
    width: 20;
    height: 20;
    property real dir: 0;                   //0: up;  1: right;  2: down; 3: left;
    onPaint: {
        var ctx = getContext("2d")
        ctx.fillStyle = Qt.rgba(0.1,0.1,0.1,0.7);
        ctx.clearRect(0,0,width,height)
        ctx.fillRect(0,0,width,height)
        ctx.beginPath();
        switch(dir)
        {
        case 0:     //up;
            ctx.moveTo(width/2,1/4 * height);
            ctx.lineTo(width/4,3/4 * height);
            ctx.lineTo(width * 3/4, 3/4 * height);
            ctx.lineTo(width/2,1/4 *height);
            break;
        case 1:     //right;
            ctx.moveTo(width * 3/4,1/2 * height);
            ctx.lineTo(width/4,1/4 * height);
            ctx.lineTo(width/4, 3/4 * height);
            ctx.lineTo(width * 3/4,1/2 *height);
            break;
        case 2:     //down;
            ctx.moveTo(width/2,3/4 * height);
            ctx.lineTo(width * 3/4,1/4 * height);
            ctx.lineTo(width * 1/4, 1/4 * height);
            ctx.lineTo(width/2,3/4 *height);
            break;
        case 3:     //left;
            ctx.moveTo(width/4,1/2 * height);
            ctx.lineTo(width *3/4,3/4 * height);
            ctx.lineTo(width * 3/4, 1/4 * height);
            ctx.lineTo(width/4,1/2 *height);
            break;
        }
        ctx.closePath();
        ctx.fillStyle = Qt.rgba(1,1,1,0.7);
        ctx.fill();
    }
}

然后,自定义整个滚动条:

import QtQuick 2.0

Rectangle {
    property Item  attachItem;
    property bool bHScroll: false;
    property real barSize : 20;
    property bool bSpace: false;                //是否留空;
    property real size: 1;

    color:Qt.rgba(0.1,0.1,0.1,0.1);
    border.color:Qt.rgba(0.8,0.8,0.8,0.8);
    border.width: 1;
    width: bHScroll ? attachItem.width : barSize;
    height: bHScroll ? barSize : attachItem.height;
    anchors{
        left: bHScroll ? attachItem.left : undefined;
        right: attachItem.right;
        top: bHScroll? undefined : attachItem.top;
        bottom: attachItem.bottom;
        rightMargin: bHScroll? (bSpace? barSize: 0): undefined;
        bottomMargin: bHScroll? undefined: (bSpace? barSize: 0)
    }
    function scroll(dir)
    {
        var step;

            if( bHScroll)
            {
                step= (scrollBtnArea.width  - btnRect.width)/10;
                if( dir  < 0 )      //left scroll;
                    btnRect.x=  btnRect.x - step > 0? btnRect.x - step : 0;
                else
                    btnRect.x = btnRect.x + step <  scrollBtnArea.width - btnRect.width? btnRect.x + step : scrollBtnArea.width - btnRect.width ;
            }else{
                step = (scrollBtnArea.height - btnRect.height)/10;
                if( dir < 0 )
                    btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ;
                else
                    btnRect.y = btnRect.y + step < scrollBtnArea.height - btnRect.height? btnRect.y + step : scrollBtnArea.height - btnRect.height;
            }
    }

    Arrow{
        id: arrow1;
        anchors{
            left: parent.left;
            top: parent.top;
            bottom: bHScroll ? parent.bottom : undefined;
            right: bHScroll ? undefined:parent.right;
        }
        width: barSize;
        height: barSize;
        dir: bHScroll? 3: 0;
        MouseArea{
            anchors.fill: parent;
            onClicked:{
                var step =2;
                if(bHScroll)
                {
                    btnRect.x = btnRect.x - step > 0? btnRect.x - step : 0;
                }else{
                    btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ;
                }
            }
        }
    }

    Rectangle{
        id: scrollBtnArea;
        color:Qt.rgba(0.1,0.1,0.1,0.7);
        anchors{
            left: bHScroll? arrow1.right : parent.left;
            right: bHScroll? arrow2.left : parent.right;
            top: bHScroll? parent.top: arrow1.bottom;
            bottom: bHScroll? parent.bottom : arrow2.top;
        }
        Rectangle{
            id: btnRect;
            x: bHScroll?  0 : 2;
            y: bHScroll?  2:  0;
            width: bHScroll?  parent.width/size : barSize -4;
            height: bHScroll? barSize -4 : parent.height/size;
            color:Qt.rgba(0.1,0.1,0.1,0.7);
            border.color: Qt.rgba(1,1,1,0.2);
            border.width: 1;
            onXChanged:{
                if(bHScroll)
                {
                    var children = attachItem.children;
                    for( var child in children)
                    {
                           var  ratio =btnRect.x/(arrow2.x - btnRect.width)
                           children[child].x= - ratio * ( size - 1) * attachItem.width ;
                        console.log("x changed:"+ btnRect.x +";"+arrow1.x+";"+arrow1.width+";"+arrow2.x +";" + btnRect.width+";"+ratio + ";"+ children[child].x +";" + size + ";" + attachItem.width);
                    }
                }
            }
            onYChanged:{
                console.log("y changed");
                if( !bHScroll)
                {
                    var children = attachItem.children;
                    for( var child in children)
                    {
                        children[child].y = -btnRect.y/(arrow2.y - btnRect.height) * ( size- 1) * attachItem.height;
                    }
                }
            }
        }

        MouseArea{
            id:mouseFunc;
            hoverEnabled: true;
            anchors.fill: parent;
            acceptedButtons: Qt.AllButtons
            drag.target: btnRect;
            drag.axis: bHScroll? Drag.XAxis : Drag.YAxis;
            drag.minimumX: 0
            drag.maximumX: bHScroll? arrow2.x - btnRect.width: 0;
            drag.minimumY: 0
            drag.maximumY:  bHScroll?  0: arrow2.y - btnRect.height ;
            onWheel:{
                console.log(" mouse wheel  event")
                var step;
                if( bHScroll )
                {
                    step= (parent.width  - btnRect.width)/10;
                    if( wheel.angleDelta.y  > 0 )
                        btnRect.x=  btnRect.x - step > 0? btnRect.x - step : 0;
                    else
                        btnRect.x = btnRect.x + step <  parent.width - btnRect.width? btnRect.x + step : parent.width - btnRect.width ;
                }else
                {
                    step = (parent.height - btnRect.height)/10;
                    if(wheel.angleDelta.y >0 )
                        btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ;
                    else
                        btnRect.y = btnRect.y + step < parent.height - btnRect.height? btnRect.y + step : parent.height - btnRect.height;
                }
            }
            onClicked:{
                var step
                if(bHScroll)
                {
                        step= (parent.width  - btnRect.width)/10;
                        if( mouseX < btnRect.x)
                        {
                            btnRect.x = btnRect.x - step > 0? btnRect.x - step : 0;
                        }else if(  mouseX > btnRect.x )
                        {
                            btnRect.x = btnRect.x + step <  parent.width - btnRect.width? btnRect.x + step : parent.width - btnRect.width ;
                        }
                }else{
                    step = (parent.height - btnRect.height)/10;
                    if( mouseY < btnRect.y )
                    {
                        btnRect.y = btnRect.y - step >0 ? btnRect.y - step: 0 ;
                    }else if(mouseY > btnRect.y){
                        btnRect.y = btnRect.y + step < parent.height - btnRect.height? btnRect.y + step : parent.height - btnRect.height;
                    }
                }
            }
        }
    }


    Arrow{
        id: arrow2;
        anchors{
            left: bHScroll?undefined: parent.left;
            top: bHScroll? parent.top: undefined;
            bottom:  parent.bottom;
            right: parent.right;
        }
        width: barSize;
        height:  barSize;
        dir: bHScroll?1:2;
        MouseArea{
            anchors.fill: parent;
            onClicked:{
                var step = 2;
                if(bHScroll)
                {
                    btnRect.x = btnRect.x + step < scrollBtnArea.width - btnRect.width? btnRect.x + step :  scrollBtnArea.width -btnRect.width;
                 }else{
                    btnRect.y = btnRect.y + step < scrollBtnArea.height - btnRect.height? btnRect.y + step : scrollBtnArea.height - btnRect.height;
                }
            }
        }
    }
}    

使用实例:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

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


    Rectangle {
        id: frame
        clip: true
        width: 200
        height: 200
        border.color: "black"
        anchors.centerIn: parent
        Image {
            id: content;
            source: "tvline.jpg"
            width: 500;
            height: 500;
        }
        MouseArea{
            anchors.fill: parent;
            onWheel:{
                if(wheel.modifiers & Qt.ControlModifier)
                {
                    if( wheel.angleDelta.y > 0)
                        hscroll.scroll(-1);
                    else
                        hscroll.scroll(1);
                    return;
                }
                //单纯的滚动;
                if( wheel.angleDelta.y > 0)
                    vscroll.scroll(-1)
                else
                    vscroll.scroll(1)
            }
        }
    }
    UI_ScrollBar{
        id: vscroll;
        visible: content.height > frame.height;
        attachItem: frame;
        bHScroll: false;
        bSpace:  hscroll.visible;
        size: content.height/frame.height;
    }


    UI_ScrollBar{
        id:hscroll;
        visible:content.width > frame.width;
        attachItem: frame;
        bHScroll: true;
        bSpace: vscroll.visible;
        size: content.width/frame.width;
    }

}

  

猜你喜欢

转载自www.cnblogs.com/yinwei-space/p/9317503.html