間輸入控件實(shí)戰(zhàn)指南:基于 date_and_time 示例解析 DateInput 與 TimeInput)
跨平臺(tái)UI組件桌面應(yīng)用【免費(fèi)下載鏈接】togaA Python native, OS native GUI toolkit.項(xiàng)目地址https://gitcode.com/gh_mirrors/to/toga點(diǎn)擊查看免費(fèi)下載導(dǎo)讀本文以 Toga 官方示例 examples/date_and_time 為藍(lán)本系統(tǒng)講解 Toga 中日期輸入控件DateInput與時(shí)間輸入控件TimeInput的完整用法包括參數(shù)語(yǔ)義、min/max邊界約束、value的類(lèi)型轉(zhuǎn)換與自動(dòng)裁剪、on_change回調(diào)的掛載方式以及如何在桌面端Windows/macOS與 Android 端一鍵運(yùn)行。讀完本文你將能夠獨(dú)立寫(xiě)出帶日期/時(shí)間范圍限制、實(shí)時(shí)回調(diào)校驗(yàn)的表單控件代碼并理解其底層實(shí)現(xiàn)原理。1. 示例概覽這個(gè)應(yīng)用在演示什么date_and_time是 Toga 倉(cāng)庫(kù)中用于測(cè)試日期與時(shí)間輸入控件的示例應(yīng)用。它在同一個(gè)窗口中展示了 8 行輸入控件覆蓋了兩種控件與三種參數(shù)組合的全部排列控件場(chǎng)景演示要點(diǎn)DateInput無(wú)限制Any date默認(rèn)取當(dāng)天日期DateInput僅設(shè)min限制可選最早日期DateInput僅設(shè)max限制可選最晚日期DateInput同時(shí)設(shè)minmax完整區(qū)間約束TimeInput無(wú)限制Any time默認(rèn)取當(dāng)前時(shí)間TimeInput僅設(shè)min限制可選最早時(shí)間TimeInput僅設(shè)max限制可選最晚時(shí)間TimeInput同時(shí)設(shè)minmax完整區(qū)間約束示例源碼位于 examples/date_and_time/date_and_time/app.py共約 140 行邏輯非常緊湊每行輸入控件都配有右側(cè)固定寬度的標(biāo)簽用戶在控件中修改日期/時(shí)間時(shí)應(yīng)用會(huì)實(shí)時(shí)把當(dāng)前值以格式化文本打印到控制臺(tái)。平臺(tái)可用性說(shuō)明官方 README 明確指出日期/時(shí)間輸入控件僅在Android、macOS 和 Windows平臺(tái)上可用。不過(guò)從倉(cāng)庫(kù)源碼結(jié)構(gòu)看gtk、qt、iOS、web等后端也各自提供了dateinput.py/timeinput.py實(shí)現(xiàn)見(jiàn) gtk/src/toga_gtk/widgets/dateinput.py、qt/src/toga_qt/widgets/timeinput.py 等具體能力以各平臺(tái)文檔為準(zhǔn)。2. 快速上手從克隆到運(yùn)行官方 README 給出了兩種啟動(dòng)方式下面逐一展開(kāi)。2.1 在 Windows / macOS 桌面端運(yùn)行$ python -m pip install toga $ python -m date_and_time兩條命令分別完成安裝 Toga 核心包以模塊方式啟動(dòng)示例。示例包內(nèi) examples/date_and_time/date_and_time/main.py 提供了模塊入口from date_and_time.app import main if __name__ __main__: main().main_loop()main()返回一個(gè)DateAndTimeApp實(shí)例隨后調(diào)用其main_loop()進(jìn)入事件循環(huán)。2.2 在 Android 上運(yùn)行$ python -m pip install briefcase $ briefcase run androidAndroid 端需要借助 Briefcase 工具鏈打包運(yùn)行。示例的 examples/date_and_time/pyproject.toml 已經(jīng)預(yù)先配置好了 Briefcase 構(gòu)建描述應(yīng)用標(biāo)識(shí)為org.beeware.toga.examples包名date_and_time版本0.0.1許可證 BSD-3-Clause[tool.briefcase.app.date_and_time]段聲明了源碼目錄date_and_time及核心依賴(lài)../../travertino、../../core各平臺(tái)段分別掛載對(duì)應(yīng)后端macOS 用cocoa、Linux 用gtk、Windows 用winforms、iOS 用iOS、Android 用android、Web 用webAndroid 段額外指定了 Material 主題Theme.MaterialComponents.Light.DarkActionBar和com.google.android.material:material:1.12.0依賴(lài)說(shuō)明 Android 上的日期/時(shí)間控件基于 Material 組件實(shí)現(xiàn)。3. 控件構(gòu)造一個(gè)窗口里的 8 行輸入示例的startup()方法用toga.Box組合所有控件。以日期行為例每個(gè)輸入控件與一個(gè)寬度 150px、右對(duì)齊的標(biāo)簽排成一行any_date_box toga.Box( children[ toga.Label(Any date:, width150, text_alignRIGHT), toga.DateInput( idAny, valueNone, on_changeself.changed_date, ), ], directionROW, )隨后將所有行放入directionCOLUMN的垂直容器中作為主窗口內(nèi)容self.main_window.content toga.Box( children[ any_date_box, min_date_box, max_date_box, min_max_date_box, any_time_box, min_time_box, max_time_box, min_max_time_box, ], directionCOLUMN, ) self.main_window.show()3.1 控件的四個(gè)核心參數(shù)從接口定義core/src/toga/widgets/dateinput.py、core/src/toga/widgets/timeinput.py可以看出兩個(gè)控件的構(gòu)造參數(shù)完全對(duì)稱(chēng)參數(shù)類(lèi)型默認(rèn)行為說(shuō)明idstr \| NoneNone控件唯一標(biāo)識(shí)回調(diào)中可通過(guò)widget.id區(qū)分是哪個(gè)控件styleStyleT \| None默認(rèn)樣式可傳入 Pack 樣式對(duì)象valuedate/time \| NoneNone時(shí)取當(dāng)天/當(dāng)前時(shí)間初始顯示值mindate/time \| NoneNone時(shí)取全局最小值可選的最早日期/時(shí)間含maxdate/time \| NoneNone時(shí)取全局最大值可選的最晚日期/時(shí)間含on_change回調(diào)函數(shù)None值變化時(shí)觸發(fā)另支持通過(guò)**kwargs傳入width等樣式屬性其中width150這類(lèi)額外關(guān)鍵字會(huì)直接應(yīng)用到控件的 Pack 樣式中。3.2 回調(diào)拿到變化后的值示例為日期和時(shí)間各注冊(cè)了一個(gè)回調(diào)用strftime做本地化格式化輸出def changed_date(self, widget): print(f{widget.id} is {widget.value.strftime(%A %d %B %Y)}) def changed_time(self, widget): print(f{widget.id} is {widget.value.strftime(%I:%M:%S %p)})回調(diào)簽名統(tǒng)一為handler(widget)Toga 通過(guò) core/src/toga/handlers.py 的wrapped_handler包裝用戶函數(shù)因此回調(diào)只會(huì)收到被觸發(fā)的控件對(duì)象你可以直接讀取widget.value并借助widget.id判斷是哪個(gè)輸入框發(fā)生了變化。運(yùn)行示例后在任一輸入框修改值終端就會(huì)打印類(lèi)似Min is Friday 02 April 2021或Max time is 10:42:00 AM的信息。4. 邊界約束min / max 的底層行為這是示例中最有實(shí)踐價(jià)值的部分min與max不僅限制用戶可選范圍還會(huì)對(duì)value進(jìn)行自動(dòng)裁剪clipping。4.1 DateInput 的取值規(guī)則示例展示了四種寫(xiě)法直接傳date對(duì)象、傳 ISO 格式字符串、或留空。其內(nèi)部轉(zhuǎn)換邏輯在 core/src/toga/widgets/dateinput.pyNone→date.today()當(dāng)天datetime.datetime→ 提取.date()部分str→datetime.date.fromisoformat()解析如2021-01-01其他類(lèi)型 → 拋TypeError(Not a valid date value)。同時(shí)模塊頂部定義了全局支持范圍dateinput.pyMIN_DATE datetime.date(1800, 1, 1) MAX_DATE datetime.date(8999, 12, 31)min未指定時(shí)默認(rèn)為1800-01-01max未指定時(shí)默認(rèn)為8999-12-31含min/max超出該范圍會(huì)拋ValueError如 The lowest supported date is 1800-01-01但value超出范圍不會(huì)報(bào)錯(cuò)而是被裁剪到最近的合法邊界。4.2 裁剪的三種聯(lián)動(dòng)場(chǎng)景設(shè)置value、min、max時(shí)存在聯(lián)動(dòng)裁剪見(jiàn) dateinput.py 與 timeinput.pyvalue越界設(shè)置value時(shí)若小于min則被抬升為min若大于max則被壓低為max調(diào)大min若當(dāng)前value早于新minvalue被裁剪為新min若max早于新minmax也被一并抬升調(diào)小max若當(dāng)前value晚于新maxvalue被裁剪為新max若min晚于新maxmin也被一并壓低。這些行為均有測(cè)試覆蓋。例如 core/tests/widgets/test_dateinput.py 的test_value_clipping驗(yàn)證了2010-01-012020-01-01區(qū)間內(nèi)把value設(shè)為2005-06-12會(huì)被裁剪為2010-01-01test_timeinput.py 的test_min_clip則驗(yàn)證了當(dāng)min抬高越過(guò)當(dāng)前value時(shí)value會(huì)被同步裁剪并觸發(fā)一次on_change。4.3 TimeInput 的特有規(guī)則時(shí)間控件的范圍邊界為00:00:00min 默認(rèn)值到23:59:59max 默認(rèn)值見(jiàn) timeinput.py)。它的值轉(zhuǎn)換timeinput.py與日期控件類(lèi)似但有兩處差異None→datetime.datetime.now().time()當(dāng)前時(shí)刻返回前統(tǒng)一replace(microsecond0)微秒永遠(yuǎn)歸零。平臺(tái)差異提示API 文檔docs/en/reference/api/widgets/timeinput.md注明在 Android 和 iOS 上秒也會(huì)歸零且min/max中設(shè)置的秒數(shù)會(huì)被忽略——移動(dòng)端時(shí)間選擇器通常只精確到分鐘。另外 docs/en/reference/api/widgets/dateinput.md 提到 iOS 上無(wú)法定制日期控件的顏色/背景樣式Apple 未提供相關(guān) API。5. 示例的四種邊界組合寫(xiě)法直接給出示例中可復(fù)制的完整寫(xiě)法節(jié)選自 app.py僅設(shè)最小值toga.DateInput( idMin, valueNone, on_changeself.changed_date, min2021-01-01, # ISO 字符串也可直接傳入 )僅設(shè)最大值toga.DateInput( idMax, valuedate(2021, 4, 2), on_changeself.changed_date, maxdate(2022, 2, 1), )同時(shí)設(shè)置區(qū)間toga.DateInput( idMin-max, valuedate(2021, 4, 2), on_changeself.changed_date, mindate(2021, 1, 1), maxdate(2022, 2, 1), )時(shí)間控件對(duì)應(yīng)寫(xiě)法時(shí)/分/秒toga.TimeInput( idMin-max time, valuetime(10, 42), on_changeself.changed_time, mintime(8, 15), maxtime(21, 30), )注意示例中min使用了字符串06:35:00、max使用了time對(duì)象兩種形式等價(jià)valuetime(10, 42)表示10:42:00缺失的秒自動(dòng)補(bǔ)零。6. 事件觸發(fā)的時(shí)機(jī)驗(yàn)證一個(gè)容易被忽略的細(xì)節(jié)構(gòu)造時(shí)即使傳入了on_change回調(diào)也不會(huì)在創(chuàng)建控件時(shí)被調(diào)用。核心測(cè)試對(duì)此有明確斷言test_dateinput.py# The change handler isnt invoked at construction. on_change_handler.assert_not_called()而每次通過(guò)屬性賦值改變value時(shí)回調(diào)會(huì)且只會(huì)被調(diào)用一次即使賦值前后值相同。wrapped_handler會(huì)在值實(shí)際寫(xiě)入底層實(shí)現(xiàn)后觸發(fā)事件測(cè)試用例 test_value 中assert_called_once_with(widget)即驗(yàn)證了這一點(diǎn)。非法值則會(huì)在賦值階段直接拋出異常測(cè)試覆蓋了兩類(lèi)情況test_dateinput.py非法輸入異常類(lèi)型消息123、object()、time對(duì)象TypeErrorNot a valid date valuenot a dateValueErrorInvalid isoformat string: not a date7. 小結(jié)與擴(kuò)展建議date_and_time示例雖然只有 140 行卻完整演示了 Toga 日期/時(shí)間控件的核心能力value的類(lèi)型寬容date/time/datetime/ISO 字符串/None、min/max的自動(dòng)裁剪聯(lián)動(dòng)、以及on_change回調(diào)的掛載與觸發(fā)時(shí)機(jī)。基于它你可以快速擴(kuò)展出實(shí)際業(yè)務(wù)場(chǎng)景例如將回調(diào)中的print替換為表單校驗(yàn)實(shí)時(shí)判斷所選日期是否在工作日或未來(lái)結(jié)合value的字符串解析能力從后端接口返回的 ISO 字符串直接初始化控件利用widget.id區(qū)分多個(gè)輸入框復(fù)用同一個(gè)回調(diào)處理一整組日期/時(shí)間字段。若需深入了解每個(gè)參數(shù)的完整語(yǔ)義可繼續(xù)閱讀官方 API 文檔 DateInput 參考 與 TimeInput 參考想驗(yàn)證控件在各種邊界條件下的行為可查看核心測(cè)試 test_dateinput.py 與 test_timeinput.py。贊分享跨平臺(tái)UI組件桌面應(yīng)用【免費(fèi)下載鏈接】togaA Python native, OS native GUI toolkit.項(xiàng)目地址https://gitcode.com/gh_mirrors/to/toga點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Toga TimeInput 時(shí)間選擇控件屬性、事件與跨平臺(tái)實(shí)現(xiàn)解析Toga TimeInput 時(shí)間選擇控件屬性、事件與跨平臺(tái)實(shí)現(xiàn)解析 TimeInput 是 Toga 中用于讓用戶選擇一天中某一時(shí)刻時(shí)、分、秒的本地化原跨平臺(tái)UI組件桌面應(yīng)用Toga DateInput 日期選擇控件從基礎(chǔ)用法到跨平臺(tái)實(shí)現(xiàn)原理Toga DateInput 日期選擇控件從基礎(chǔ)用法到跨平臺(tái)實(shí)現(xiàn)原理 本文是 TogaA Python native, OS native GUI tool跨平臺(tái)UI組件桌面應(yīng)用ESP32 溫控 PID 閉環(huán)實(shí)戰(zhàn)從原始 ADC 讀數(shù)到穩(wěn)定的加熱功率輸出ESP32 溫控 PID 閉環(huán)實(shí)戰(zhàn)從原始 ADC 讀數(shù)到穩(wěn)定的加熱功率輸出 設(shè)溫 25°C實(shí)際沖到 31°C 才慢慢回落到 24°C——這是第一次跑溫控閉環(huán)嵌入式物聯(lián)網(wǎng)驅(qū)動(dòng)開(kāi)發(fā)上一篇網(wǎng)絡(luò)設(shè)備權(quán)限解鎖全攻略三步開(kāi)啟永久管理通道下一篇ESP芯片燒錄終極指南如何用esptool.py輕松搞定固件編程創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考