QML 使用PathView制作日期选择
先看效果
可以实现切换月份时日期天数增加减少,润年时2月份设置29天,源码很简单
///准备部分
ListModel{
id: listmodel_year
ListElement{yname:"2019"} ListElement{yname:"2020"} ListElement{yname:"2021"}
}
Component{
id: com_delegate_year
Column{
id: wrapper_year
Text {
id: nameText
text: yname
color: wrapper_year.PathView.isCurrentItem ? "#14c0f5" : "#dcdcdc"
}
}
}
ListModel{
id:listmodel_start_month
ListElement{startmname:"01"} ListElement{startmname:"02"} ListElement{startmname:"03"} ListElement{startmname:"04"} ListElement{startmname:"05"}
ListElement{startmname:"06"} ListElement{startmname:"07"} ListElement{startmname:"08"} ListElement{startmname:"09"} ListElement{startmname:"10"}
ListElement{startmname:"11"} ListElement{startmname:"12"}
}
Component{
id: com_delegate_start_month
Column{
id: wrapper_start_month
Text {
id: txt_home_date_start_month
text: startmname
color: wrapper_start_month.PathView.isCurrentItem ? "#14c0f5" : "#dcdcdc"
}
}
}
ListModel{
id:listmodel_stop_month
ListElement{stopmname:"01"} ListElement{stopmname:"02"} ListElement{stopmname:"03"} ListElement{stopmname:"04"} ListElement{stopmname:"05"}
ListElement{stopmname:"06"} ListElement{stopmname:"07"} ListElement{stopmname:"08"} ListElement{stopmname:"09"} ListElement{stopmname:"10"}
ListElement{stopmname:"11"} ListElement{stopmname:"12"}
}
Component{
id: com_delegate_stop_month
Column{
id: wrapper_stop_month
Text {
id: txt_home_date_stop_month
text: stopmname
color: wrapper_stop_month.PathView.isCurrentItem ? "#14c0f5" : "#dcdcdc"
}
}
}
ListModel{
id: listmodel_start_day
ListElement{startdname:"01"} ListElement{startdname:"02"} ListElement{startdname:"03"} ListElement{startdname:"04"} ListElement{startdname:"05"}
ListElement{startdname:"06"} ListElement{startdname:"07"} ListElement{startdname:"08"} ListElement{startdname:"09"} ListElement{startdname:"10"}
ListElement{startdname:"11"} ListElement{startdname:"12"} ListElement{startdname:"13"} ListElement{startdname:"14"} ListElement{startdname:"15"}
ListElement{startdname:"16"} ListElement{startdname:"17"} ListElement{startdname:"18"} ListElement{startdname:"19"} ListElement{startdname:"20"}
ListElement{startdname:"21"} ListElement{startdname:"22"} ListElement{startdname:"23"} ListElement{startdname:"23"} ListElement{startdname:"25"}
ListElement{startdname:"26"} ListElement{startdname:"27"} ListElement{startdname:"28"} ListElement{startdname:"29"} ListElement{startdname:"30"}
ListElement{startdname:"31"}
}
Component{
id: com_delegate_start_day
Column{
id: wrapper_start_day
Text {
id: txt_home_date_start_day
text: startdname
color: wrapper_start_day.PathView.isCurrentItem ? "#14c0f5" : "#dcdcdc"
}
}
}
///显示部分
Rectangle{//起
id: rec_home_date_start
width: btn_home_premonth.width / 2
height: width * 5/2 - 3
anchors.top: parent.top
anchors.topMargin: 3
anchors.left: parent.left
anchors.leftMargin: 3
Image {
source: "images/label1_2.png"
anchors.fill: parent
}
Text {
text: qsTr("起")
anchors.centerIn: parent
}
}
Rectangle{//起始年
id:rec_home_date_start_year
width: btn_home_premonth.width
height: width / 2
anchors.left: rec_home_date_start.right
anchors.leftMargin: 3
y:(rec_home_date_start.height - height) / 2 + 5
Image {
source: "images/calendar.png"
anchors.fill: parent
}
PathView{
id: pathview_start_year
anchors.fill: parent
model:listmodel_year
delegate: com_delegate_year
pathItemCount: 3
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
path: Path{
startX: parent.width / 10
startY: -30
PathLine{x:parent.width / 10; y:25}
PathLine{x:parent.width / 10; y:45}
PathLine{x:parent.width / 10; y:65}
}
onCurrentIndexChanged: {
if ((currentIndex + 2019)%4 == 0)//润年
{
if (pathview_start_month.currentIndex == 1 && listmodel_start_day.count == 28)//2月
{
listmodel_start_day.insert(28, {startdname:"29"})
}
}else{
if (pathview_start_month.currentIndex == 1 && listmodel_start_day.count == 29)//2月
{
listmodel_start_day.remove(28)
}
}
}
}
}
Rectangle{//起始年label
id: label_home_date_start_year
height: rec_home_date_start_year.height
width: height
anchors.left: rec_home_date_start_year.right
anchors.top: rec_home_date_start_year.top
Text {
text: qsTr("年")
anchors.centerIn: parent
}
}
Rectangle{//起始月
id: rec_home_date_start_month
height: rec_home_date_start_year.height
width: height
anchors.left: label_home_date_start_year.right
anchors.top: label_home_date_start_year.top
Image {
source: "images/calendar.png"
anchors.fill: parent
}
PathView{
id: pathview_start_month
anchors.fill: parent
model: listmodel_start_month
delegate: com_delegate_start_month
pathItemCount: 3
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
path: Path{
startX: parent.width / 20
startY: -30
PathLine{x:parent.width / 20; y:25}
PathLine{x:parent.width / 20; y:45}
PathLine{x:parent.width / 20; y:65}
}
onCurrentIndexChanged: {//
console.log("取余: " + (pathview_start_year.currentIndex + 2019)%4)
if (currentIndex == 1)//2月
{//2月上下都为31天
if ((pathview_start_year.currentIndex + 2019)%4 == 0)//润年
{
listmodel_start_day.remove(30)//31日
listmodel_start_day.remove(29)//30日
}else{
listmodel_start_day.remove(30)//31日
listmodel_start_day.remove(29)//30日
listmodel_start_day.remove(28)//29日
}
}else if (currentIndex == 3 || currentIndex == 5 || currentIndex == 8 || currentIndex == 10){//4、6、9、11月,30天
listmodel_start_day.remove(30)//30天这些月份,之前之后的月份都是31天
}else if (currentIndex == 0 || currentIndex == 2 || currentIndex == 4 || currentIndex == 6 || currentIndex == 7 || currentIndex == 9 || currentIndex == 11){
//1、3、5、7、8、10、12月
if (listmodel_start_day.count == 28)
{
listmodel_start_day.insert(28, {startdname:"29"})
listmodel_start_day.insert(29, {startdname:"30"})
listmodel_start_day.insert(30, {startdname:"31"})
}else if (listmodel_start_day.count == 29){
listmodel_start_day.insert(29, {startdname:"30"})
listmodel_start_day.insert(30, {startdname:"31"})
}else if (listmodel_start_day.count == 30){
listmodel_start_day.insert(30, {startdname:"31"})
}
}
}
}
}
Rectangle{//起始月label
id: label_home_date_start_month
height: rec_home_date_start_month.height
width: height
anchors.left: rec_home_date_start_month.right
anchors.top: rec_home_date_start_month.top
Text {
text: qsTr("月")
anchors.centerIn: parent
}
}
Rectangle{//起始日
id:rec_home_date_start_day
height: rec_home_date_start_month.height
width: height
anchors.left: label_home_date_start_month.right
anchors.top: label_home_date_start_month.top
Image {
source: "images/calendar.png"
anchors.fill: parent
}
PathView{
id: pathview_start_day
anchors.fill: parent
model: listmodel_start_day
delegate: com_delegate_start_day
pathItemCount: 3
preferredHighlightBegin: 0.5
preferredHighlightEnd: 0.5
path: Path{
startX: parent.width / 20
startY: -30
PathLine{x:parent.width / 20; y:25}
PathLine{x:parent.width / 20; y:45}
PathLine{x:parent.width / 20; y:65}
}
}
}
Rectangle{//起始月label
id: label_home_date_start_day
height: rec_home_date_start_day.height
width: height
anchors.left: rec_home_date_start_day.right
anchors.top: rec_home_date_start_day.top
Text {
text: qsTr("日")
anchors.centerIn: parent
}
}
效果就是开始的图那样了
附参考:
https://my.oschina.net/u/1170641/blog/285004?p={{page}}
https://blog.csdn.net/foruok/article/details/38060495
下面这个链接的效果更好
http://www.qter.org/portal.php?mod=view&aid=20