zoukankan      html  css  js  c++  java
  • QML 自定义Calendar控件

    日历控件是基于 Qt5.x 以上,导入 QtQuick.Controls.1.2 即可使用。在看我这篇博客之前,最好选择 Calendar 按 F1 查看 Qt Creator 的帮助文档,或者查看 Calendar 的官方文档所在网页,因为我这篇博客也基本上参考的官方文档,只是在其基础上写了个 Demo。

    一、展示

    x先看下效果:

    二、属性、信号和方法

    2.1 属性

    日历控件使用 style:CalendarStyle 设置样式,常用属性如下:

    • gridVisible : bool

      网格是否可见。默认为真

    • gridColor : color

      网格线的颜色

    • background : Component

      日历的背景。日历的隐式尺寸的计算基于背景的隐式尺寸

    • navigationBar : Component

      导航条的样式。在日历的顶部,包含下个月,上个月和选择的日期 Label

    • dayDelegate : Component

      主要设置日期的样式

    • dayOfWeekDelegate : Component

      每周的样式。周天的高度基于隐式的显示框的高度计算

    • weekNumberDelegate : Component

      周数的样式。显示框的隐式宽用来计算周数的宽

    下面的数据会提供给 dayDelegate 的组件:

    styleData.date 样式中的日期,属性为date
    styleData.selected 如果为真,日期被选择 属性为bool
    styleData.index 这个delegate的索引 属性为int
    styleData.valid 日期有效则为真,属性bool
    styleData.today 日期为今天,为真。属性bool
    styleData.visibleMonth 日期在今月,为真,属性bool
    styleData.hovered 鼠标悬停在这个单元,为真。即使日期无效。属性bool
    styleData.pressed 鼠标在单元按下,为真,即使日期无效。属性bool

    2.2 信号

    常用信号如下所示,这里不做过多介绍,看信号名就一目了然,实在不行查看官方文档:

    // Signals
    clicked(date date)
    doubleClicked(date date)
    hovered(date date)
    pressed(date date)
    released(date date)
    

    2.3 方法

    常用方法(函数)如下所示,这里也不做过多介绍,详情查看官方文档:

    // Methods 
    showNextMonth()
    showNextYear()
    showPreviousMonth()
    showPreviousYear()
    

    三、代码

    main.qml:

    import QtQuick 2.3
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    
    Rectangle {
        visible: true
         400
        height: 440
    
        // 定时器:用于延时
        Timer {
            id: timer
        }
    
        // 计算两个时间之间的天数
        function getDays() {
            var curDate = new Date();   // 当前日期
            var endDate = calendar.selectedDate -12*60*60*1000 // 结束日期
            var day = (endDate - curDate)/1000/60/60/24
            if(day > -1.0)
                return parseInt(day+1);
            else
                return parseInt(day);
        }
    
        // 延时函数
        function delay(delayTime, cb) {
            timer.interval = delayTime;
            timer.repeat = false;
            timer.triggered.connect(cb);
            timer.start();
        }
    
        // 获得剩余天数(curDate 到 endDate)
        function getRemainDay() {
            var remainDay = 10
            return remainDay
        }
    
        // MouseArea的层级在"其它所有控件"之下(因为写在"其它所有控件"的后面,又是同级的)
        MouseArea{
            anchors.fill: parent
            onPressed: parent.forceActiveFocus() // 强制让窗口获得焦点
        }
    
        TextField {
            id: textAreaEnd
             320
            height: 40
            placeholderText: "请选择日期"
            readOnly: true // 只读
            font.pointSize: 18
            anchors.top: parent.top
            anchors.topMargin: 30
            anchors.horizontalCenter: parent.horizontalCenter
    
            // 检测焦点是否在文本输入框中,在则弹出"日历"
            onFocusChanged: {
                if (activeFocus)
                    calendar.visible = true
                else
                    calendar.visible = false
            }
    
            // 避免选择日期后"日历"隐藏,焦点此时还在"文本框"上,无法进入"焦点改变事件"显示"日历"的情况
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    calendar.visible = true
                    parent.forceActiveFocus()
                }
            }
        }
    
        // 日历控件
        Calendar {
            id: calendar
            anchors.top: textAreaEnd.bottom
            anchors.left: textAreaEnd.left
             textAreaEnd.width
            height: 320
            visible: false
            minimumDate: new Date()
    
            // 日历样式
            style: CalendarStyle {
                gridVisible: false // 网格不可见
    
    
                // 设置日期的样式
                dayDelegate: Rectangle {
    
                    // 日期是否为今天
                    property bool bIsToday: styleData.date.toLocaleString(Qt.locale("de_DE"), "yyyy-MM-dd") ===
                                            (new Date()).toLocaleString(Qt.locale("de_DE"), "yyyy-MM-dd")
    
                    gradient: Gradient {
                        GradientStop {
                            position: 0.00
                            color: styleData.selected && styleData.date >= new Date() ? "SlateGray" : "white"
                        }
                    }
    
                    Label {
                        id: labDay
                        text: styleData.date.getDate()
                        font.family: "Microsoft YaHei"
                        font.pixelSize: 16
                        anchors.centerIn: parent
                        color: (styleData.date > new Date() && styleData.selected) ? "white" :
                               ((styleData.date > new Date() && styleData.visibleMonth)
                               ? (bIsToday ? "blue" : "black") : "Silver")
                    }
                }
            }
    
            // 选择结束日期之后,隐藏日历
            onClicked: {
                textAreaEnd.text = Qt.formatDateTime(calendar.selectedDate, "yyyy-MM-dd")            
    
                // 延时一会儿才隐藏日历(第二个参数为"函数")
                delay(200, function() {calendar.visible = false})
            }
        }
    }
    
    

    实现功能:

    • 设置日历控件的今天前的日期为"不可选状态";

    • 点击 TextField 弹出日历,点击窗口空白区域隐藏日历;

    • 选择日期之后,延时隐藏日历;

    • 计算今天与选择日期之间的天数。

    四、代码下载

    GitHub 下载链接:https://github.com/confidentFeng/QML_Demo/tree/master/CalendarUse


    参考:

    QML类型说明-CalendarStyle-翻译

    Qml日历

    QML2.0下的丰富的控件之日历

    QML QtQuick.Controls 1 Calendar日历样式自定义


  • 相关阅读:
    oracle 数据量少 count(1)查询慢_很高兴!终于踩到了慢查询的坑
    C#中的委托(一)
    The hierarchy of the type is inconsistent
    errors exist in required project(s) xxx proceed with launch?
    oracle数据库常用操作语句 、创建视图
    hibernate.hbm.xml必须必须配置主键
    PWC6199:Generated servlet error:Only a type can be imported. org.apache.jasper.tagplugins.jstl.core.ForEach resolves to a package
    org.apache.jasper.JasperException: /WEB-INFO/jsp/product/edit.jsp(168,45)
    unique constraint(PD.HSI_RIGHT) violated
    svn报错:“Previous operation has not finished; run 'cleanup' if it was interrupted“
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/13632176.html
Copyright © 2011-2022 走看看