日歷控件是基於 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
width: 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
width: 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
width: 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 QtQuick.Controls 1 Calendar日歷樣式自定義