目錄
- 引言
- 相關閱讀
- 項目結構
- 示例實現與代碼解析
- 示例一:時間選擇器(TimePicker)
- 示例二:日期時間選擇器(DateTimePicker)
- 主窗口整合
- 運行效果
- 總結
- 下載鏈接
引言
在現代應用程序開發中,時間與日期選擇是常見的用戶界面需求。無論是在日程安排、預約系統還是任何需要時間錄入的場景,一個直觀易用的選擇器組件可以大大提升用戶體驗。本文將詳細介紹如何使用 QML 技術實現兩種常用的選擇器組件:時間選擇器和日期時間選擇器。
相關閱讀
- Tumbler 組件文檔
項目結構
示例實現與代碼解析
本項目實現了兩個實用的選擇器組件:時間選擇器(TimePicker)和日期時間選擇器(DateTimePicker)。下面將對這些組件進行詳細解析。
示例一:時間選擇器(TimePicker)
時間選擇器允許用戶通過滾動選擇特定的小時和分鐘值。這種交互方式類似于傳統的模擬時鐘調整,但提供了更為精確和直觀的數字選擇。
核心代碼:
Rectangle {id: rootwidth: 280height: 400color: "#ffffff"radius: 10border.color: "#e0e0e0"border.width: 1property int hours: hoursTumbler.currentIndexproperty int minutes: minutesTumbler.currentIndexColumnLayout {anchors.fill: parentspacing: 10Text {Layout.alignment: Qt.AlignHCentertext: "選擇時間"font.pixelSize: 20color: "#333333"Layout.topMargin: 20}Rectangle {Layout.alignment: Qt.AlignHCenterLayout.preferredWidth: parent.width - 40Layout.preferredHeight: 200color: "transparent"Row {anchors.centerIn: parentspacing: 10Tumbler {id: hoursTumblermodel: 24height: 200width: 80delegate: Text {text: modelData.toString().padStart(2, '0')color: Tumbler.tumbler.currentIndex === index ? "#1976D2" : "#666666"font.pixelSize: Tumbler.tumbler.currentIndex === index ? 22 : 18horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenteropacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)}}Text {text: ":"font.pixelSize: 24anchors.verticalCenter: parent.verticalCentercolor: "#333333"}Tumbler {id: minutesTumblermodel: 60height: 200width: 80delegate: Text {text: modelData.toString().padStart(2, '0')color: Tumbler.tumbler.currentIndex === index ? "#1976D2" : "#666666"font.pixelSize: Tumbler.tumbler.currentIndex === index ? 22 : 18horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenteropacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)}}}}Text {Layout.alignment: Qt.AlignHCentertext: hours.toString().padStart(2, '0') + ":" + minutes.toString().padStart(2, '0')font.pixelSize: 24color: "#1976D2"}}
}
代碼解析:
外觀設計:
- 使用 Rectangle 作為容器,設置圓角和邊框,營造現代化的界面風格
- 采用簡潔的配色方案,主色調為藍色(#1976D2),與灰色搭配形成對比
- 整體布局采用垂直方向的 ColumnLayout 排列元素
時間選擇邏輯:
- 使用兩個 Tumbler 組件分別控制小時(0-23)和分鐘(0-59)
- 通過屬性綁定
property int hours: hoursTumbler.currentIndex
直接獲取選擇的值 - 實時顯示當前選擇的時間,方便用戶確認
視覺反饋:
- 當前選中項使用突出的藍色和更大的字體
- 通過 opacity 屬性實現滾輪效果,讓遠離中心的項逐漸變淡
- 使用
padStart(2, '0')
確保時間始終以兩位數顯示(如 “01” 而非 “1”)
示例二:日期時間選擇器(DateTimePicker)
日期時間選擇器擴展了時間選擇的功能,增加了年、月、日的選擇,提供了完整的日期時間設置能力。
核心代碼:
Rectangle {id: rootwidth: 320height: 480color: "#ffffff"radius: 10border.color: "#e0e0e0"border.width: 1property date selectedDateTime: new Date()function updateDateTime() {if (!yearTumbler.currentItem || !dayTumbler.currentItem) return;let newDate = new Date(selectedDateTime)let year = parseInt(yearTumbler.currentItem.text)let month = monthTumbler.currentIndexlet day = parseInt(dayTumbler.currentItem.text)let hours = hoursTumbler.currentIndexlet minutes = minutesTumbler.currentIndex// 驗證日期是否有效if (isNaN(year) || isNaN(day)) return;newDate.setFullYear(year)newDate.setMonth(month)newDate.setDate(day)newDate.setHours(hours)newDate.setMinutes(minutes)if (newDate.getTime() === selectedDateTime.getTime()) return;selectedDateTime = newDate}// 計算指定年月的天數function getDaysInMonth(year, month) {return new Date(year, month + 1, 0).getDate()}Component.onCompleted: {let currentDate = new Date()yearTumbler.currentIndex = yearTumbler.model.indexOf(currentDate.getFullYear().toString())monthTumbler.currentIndex = currentDate.getMonth()dayTumbler.currentIndex = currentDate.getDate() - 1hoursTumbler.currentIndex = currentDate.getHours()minutesTumbler.currentIndex = currentDate.getMinutes()}// ... Tumbler 組件實現 ...Text {Layout.alignment: Qt.AlignHCentertext: selectedDateTime.toLocaleString(Qt.locale(), "yyyy年MM月dd日 hh:mm")font.pixelSize: 18color: "#1976D2"}
}
代碼解析:
日期時間管理:
- 使用
property date selectedDateTime
存儲完整的日期時間信息 - 實現
updateDateTime()
函數統一處理所有 Tumbler 的變更 - 加入錯誤處理和有效性檢查,確保日期合法
月份天數處理:
- 通過
getDaysInMonth()
函數動態計算每月天數 - 在月份變化時自動調整日期選擇器的可選范圍
- 避免出現無效日期(如 2 月 31 日)
初始化與數據綁定:
- 在
Component.onCompleted
中設置初始值為當前系統時間 - 使用
Qt.callLater()
延遲更新,避免組件初始化時的問題 - 通過
toLocaleString()
格式化顯示完整的日期時間
錯誤處理與優化:
- 增加空值檢查,防止訪問空對象屬性
- 添加數據有效性驗證,避免設置非法日期
- 使用日期相等性比較,減少不必要的更新
主窗口整合
在 Main.qml 中,我們將兩個選擇器組件集成到一個統一的界面中,由于篇幅過長,此處代碼省略,詳情請看下載鏈接。
運行效果
總結
本文介紹了使用 QML 實現時間選擇器和日期時間選擇器的方法與技巧。通過這個項目,我們可以得出以下幾點經驗:
- 將 UI 元素封裝為獨立組件,增強代碼復用性和可維護性
- 加入適當的錯誤檢查和邊界條件處理,增強程序健壯性
- 充分利用 QML 的數據綁定特性,簡化狀態管理
下載鏈接
完整項目代碼可以從以下鏈接獲取:GitCode - DateTimePicker