QtQuick 日期滚动控件

来源:互联网 发布:linux ln 删除 编辑:程序博客网 时间:2024/05/18 02:03

在用QtQuick来编写时间滚动控件有两种方式,一种是用PathView设置路径点,另一种则用用ListView。本次采用ListView来制作时间滚动控件。

ListView可以直接驱动鼠标滚轮和触屏点击,非常有效。Hightlight控件在delegate件的下面,如果delegate控件的

纯文字,那么文字会显示在Highlight控件的上面,展示出文字和选中的背景。如果delegate同样为一个不透明的控件,那

hightlight将被覆盖,不会显示,并且滚动时上下边界有弹动效果不是很协调,可以通过调整z值和透明度解决(弹动效果不

能解决).

这里用的做法便是像下面这样,在底层加一个背景控件设置颜色,delegate设置为透明文字控件,hightlight就可

以显示了,文字和背景都能显示,并且顶部和底部的弹动效果,也会消失(因为delegate为纯文字)。当动时view会在顶部和

底部多一个item,可设clip去掉。如下写了一个滚动并且在下下加了渐变设置

新建文件Spanner.qml   import QtQuick 2.7Item{    id: spannerRoot    width: 30    height: titleText.height + viewRect.height    property int itemCount: 3    property int viewModel: 0    property int viewModelBase: 0    property int dataLength: 0    property string title: ""    property string currentText: view.currentItem.text    signal movementEnded    Text{        id: titleText        width: parent.width        height: 20        color: "white"        text: title        horizontalAlignment: Text.AlignHCenter        verticalAlignment: Text.AlignVCenter    }    Item{        id: viewRect        anchors.top: titleText.bottom        width: parent.width        height: itemCount * 30        ListView{            id: view            anchors.fill: parent            clip: true          //去除在拖动时顶部和底部多显示的一个item            preferredHighlightBegin: highlightItem.height            preferredHighlightEnd: 2 * highlightItem.height            highlightRangeMode: ListView.StrictlyEnforceRange            model: viewModel            delegate: Text{                width: parent.width                height: 30                horizontalAlignment: Text.AlignHCenter                verticalAlignment: Text.AlignVCenter                //设置不够位数左边用0补齐                text: (new Array(dataLength).join('0') + (viewModelBase + index)).slice(-dataLength)                color: "white"            }            highlight: Rectangle{                color: "lightgreen"            }            onMovementEnded: spannerRoot.movementEnded(); //当滚动结束时将信号导出        }        //添加一个渐变色        Rectangle{            anchors.fill: parent            gradient: Gradient {                GradientStop {                    position: 0.00;                    color: "transparent";                }                GradientStop {                    position: 0.329;                    color: "red";                }                GradientStop {                    position: 0.33;                    color: "transparent";                }                GradientStop {                    position: 0.67;                    color: "transparent";                }                GradientStop {                    position: 0.671;                    color: "red";                }                GradientStop {                    position: 1.00;                    color: "transparent";                }            }        }    }    //根据index设置ListView的当前item    function setCurrentIndex(index){        view.currentIndex = index;    }}
这样就可以生成一个滚动滚件,参数由外部设置;要生成日期滚动控件,我们需要复制三个,并做一些逻辑判断

新建文件DateEdit.qml   import QtQuick 2.0Item {    width: dateEditRow.width    height: dateEditRow.height    property var dataLengthArray: [4,2,2]    property var titleArray: ["年","月","日"]    property var modelArray: [14,12,31] //显示model范围    property var modelBaseArray: [year_base(modelArray[0]) + 1,1,1]//显示起点    property string curDate: ""    Row{        id: dateEditRow        spacing: 3        Repeater{            id: spannerRepeater            model: 3            Spanner{                itemCount: 3                      //显示的item个数                dataLength: dataLengthArray[index]//数据是几位,不够的用0在左边补齐                title: titleArray[index]          //上面的标题                viewModel: modelArray[index]      //总共可滚动的项目数                viewModelBase: modelBaseArray[index] //从哪里开始            }            onItemAdded: {                item.movementEnded.connect(autoCorrectDate); //绑定滚动结束的函数            }        }    }    Component.onCompleted: {        //初始化显示当前日期        var currentDate = new Date();        spannerRepeater.itemAt(0).setCurrentIndex(modelArray[0] - 1);        spannerRepeater.itemAt(1).setCurrentIndex(currentDate.getMonth());        spannerRepeater.itemAt(2).setCurrentIndex(currentDate.getDate() - 1);    }    function year_base(modelCount){        var curDate = new Date();        var yearBase;        if(modelArray && modelArray.length > 0)            yearBase = curDate.getFullYear() - modelCount;        else            yearBase = curDate.getFullYear() - 10;        return yearBase;    }    function autoCorrectDate(){        var year = Number(spannerRepeater.itemAt(0).currentText);        var month = Number(spannerRepeater.itemAt(1).currentText);        var day = Number(spannerRepeater.itemAt(2).currentText);        var monthType = month_type(month);        switch (monthType){        case 1:            break;        case 2:            if(is_runnian(year)){                if(day > 29)                    spannerRepeater.itemAt(2).setCurrentIndex(modelArray[2] - 3); //最大31天润年2月最大29天,31-29+1=3            }else{                if(day > 28)                    spannerRepeater.itemAt(2).setCurrentIndex(modelArray[2] - 4); //最大31天平年2月最大28天,31-28+1=4            }            break;        case 3:            if(day > 30){                spannerRepeater.itemAt(2).setCurrentIndex(modelArray[2] - 2); //最大31天小月30天,31-30+1=2            }        }        curDate = spannerRepeater.itemAt(0).currentText + '-' + spannerRepeater.itemAt(1).currentText + '-' + spannerRepeater.itemAt(2).currentText;    }    function is_runnian(year){        var cond1 = year % 4 == 0;  //条件1:年份必须要能被4整除        var cond2 = year % 100 != 0;  //条件2:年份不能是整百数        var cond3 = year % 400 ==0;  //条件3:年份是400的倍数        //当条件1和条件2同时成立时,就肯定是闰年,所以条件1和条件2之间为“与”的关系。        //如果条件1和条件2不能同时成立,但如果条件3能成立,则仍然是闰年。所以条件3与前2项为“或”的关系。        //所以得出判断闰年的表达式:        var cond = cond1 && cond2 || cond3;        if(cond) {            return true;        } else {            return false;        }    }    function month_type(month){        if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)            return 1;        else if(month == 2)            return 2;        else            return 3;    }}

以下为效果截图

原创粉丝点击