提交 db3cb5f1 编写于 作者: 之一Yo's avatar 之一Yo

添加日期选择器

上级 7af352ae
......@@ -40,7 +40,7 @@ class Config(QConfig):
YEAR = 2023
AUTHOR = "zhiyiYo"
VERSION = "v0.4.2"
VERSION = "v0.7.0"
HELP_URL = "https://pyqt-fluent-widgets.readthedocs.io"
REPO_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets"
EXAMPLE_URL = "https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/master/examples"
......
......@@ -6,13 +6,14 @@ class Translator(QObject):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.basicInput = self.tr('Basic input')
self.text = self.tr('Text')
self.view = self.tr('View')
self.menus = self.tr('Menus')
self.icons = self.tr('Icons')
self.layout = self.tr('Layout')
self.dialogs = self.tr('Dialogs')
self.material = self.tr('Material')
self.statusInfo = self.tr('Status & info')
self.scroll = self.tr('Scrolling')
self.layout = self.tr('Layout')
self.text = self.tr('Text')
self.icons = self.tr('Icons')
self.view = self.tr('View')
\ No newline at end of file
self.material = self.tr('Material')
self.dateTime = self.tr('Date & time')
self.basicInput = self.tr('Basic input')
self.statusInfo = self.tr('Status & info')
\ No newline at end of file
......@@ -26,12 +26,12 @@
<message>
<location filename="../../view/basic_input_interface.py" line="54"/>
<source>A 2-state CheckBox</source>
<translation>雙態選框</translation>
<translation>雙態選框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="63"/>
<source>A 3-state CheckBox</source>
<translation>三態選框</translation>
<translation>三態選框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="74"/>
......@@ -76,12 +76,12 @@
<message>
<location filename="../../view/basic_input_interface.py" line="54"/>
<source>Two-state CheckBox</source>
<translation>雙態選框</translation>
<translation>雙態選框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="61"/>
<source>Three-state CheckBox</source>
<translation>三態選框</translation>
<translation>三態選框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="47"/>
......@@ -96,12 +96,12 @@
<message>
<location filename="../../view/basic_input_interface.py" line="102"/>
<source>Crazy Diamond</source>
<translation>瘋狂</translation>
<translation>瘋狂</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="103"/>
<source>Soft and Wet</source>
<translation>軟又</translation>
<translation>軟又</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="82"/>
......@@ -124,6 +124,34 @@
<translation>可編輯的下拉框</translation>
</message>
</context>
<context>
<name>DateTimeInterface</name>
<message>
<location filename="../../view/date_time_interface.py" line="21"/>
<source>A simple DatePicker</source>
<translation>日期選擇器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="27"/>
<source>A DatePicker in another format</source>
<translation>另一種格式的日期選擇器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="34"/>
<source>A simple TimePicker</source>
<translation>時間選擇器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="41"/>
<source>A TimePicker using a 24-hour clock</source>
<translation>24 小時製的時間選擇器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="48"/>
<source>A TimePicker with seconds column</source>
<translation>顯示秒的時間選擇器</translation>
</message>
</context>
<context>
<name>DialogInterface</name>
<message>
......@@ -201,12 +229,12 @@
<message>
<location filename="../../view/layout_interface.py" line="20"/>
<source>Flow layout without animation</source>
<translation>不帶動畫效果的流式</translation>
<translation>不帶動畫效果的流式</translation>
</message>
<message>
<location filename="../../view/layout_interface.py" line="27"/>
<source>Flow layout with animation</source>
<translation>帶有動畫效果的流式</translation>
<translation>帶有動畫效果的流式</translation>
</message>
<message>
<location filename="../../view/layout_interface.py" line="36"/>
......@@ -226,7 +254,7 @@
<message>
<location filename="../../view/layout_interface.py" line="37"/>
<source>Crazy diamond</source>
<translation>瘋狂</translation>
<translation>瘋狂</translation>
</message>
<message>
<location filename="../../view/layout_interface.py" line="38"/>
......@@ -264,88 +292,93 @@
<message>
<location filename="../../view/icon_interface.py" line="21"/>
<source>Search icons</source>
<translation>索圖標</translation>
<translation>索圖標</translation>
</message>
</context>
<context>
<name>MainWindow</name>
<message>
<location filename="../../view/main_window.py" line="131"/>
<location filename="../../view/main_window.py" line="118"/>
<source>Home</source>
<translation>主頁</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="137"/>
<location filename="../../view/main_window.py" line="124"/>
<source>Basic input</source>
<translation>基本輸入</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="139"/>
<location filename="../../view/main_window.py" line="128"/>
<source>Dialogs</source>
<translation>對話框</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="141"/>
<location filename="../../view/main_window.py" line="130"/>
<source>Layout</source>
<translation></translation>
<translation></translation>
</message>
<message>
<location filename="../../view/main_window.py" line="145"/>
<location filename="../../view/main_window.py" line="134"/>
<source>Menus</source>
<translation>菜單</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="143"/>
<location filename="../../view/main_window.py" line="132"/>
<source>Material</source>
<translation>材料</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="147"/>
<location filename="../../view/main_window.py" line="136"/>
<source>Scrolling</source>
<translation>滾動</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="149"/>
<location filename="../../view/main_window.py" line="138"/>
<source>Status &amp; info</source>
<translation>狀態和信息</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="208"/>
<location filename="../../view/main_window.py" line="198"/>
<source>This is a help message</source>
<translation>一條友善的提示</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="208"/>
<location filename="../../view/main_window.py" line="198"/>
<source>You clicked a customized navigation widget. You can add more custom widgets by calling `NavigationInterface.addWidget()` 😉</source>
<translation>你點擊了一個自定義的導航項你可以通過 `NavigationInterface.addWidget()` 添加更多的自定義導航項</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="151"/>
<location filename="../../view/main_window.py" line="140"/>
<source>Text</source>
<translation>文本</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="133"/>
<location filename="../../view/main_window.py" line="120"/>
<source>Icons</source>
<translation>圖標</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="153"/>
<location filename="../../view/main_window.py" line="142"/>
<source>View</source>
<translation>視圖</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="163"/>
<location filename="../../view/main_window.py" line="152"/>
<source>Settings</source>
<translation>設置</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="126"/>
<source>Date &amp; time</source>
<translation>日期和時間</translation>
</message>
</context>
<context>
<name>MaterialInterface</name>
<message>
<location filename="../../view/material_interface.py" line="29"/>
<source>Acrylic label</source>
<translation>亞克力標</translation>
<translation>亞克力標</translation>
</message>
</context>
<context>
......@@ -363,7 +396,7 @@
<message>
<location filename="../../view/menu_interface.py" line="36"/>
<source>Copy</source>
<translation></translation>
<translation></translation>
</message>
<message>
<location filename="../../view/menu_interface.py" line="37"/>
......@@ -494,7 +527,7 @@
<message>
<location filename="../../view/setting_interface.py" line="85"/>
<source>Use system setting</source>
<translation>跟隨統設置</translation>
<translation>跟隨統設置</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="67"/>
......@@ -509,7 +542,7 @@
<message>
<location filename="../../view/setting_interface.py" line="74"/>
<source>Interface zoom</source>
<translation>縮放</translation>
<translation>縮放</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="74"/>
......@@ -524,7 +557,7 @@
<message>
<location filename="../../view/setting_interface.py" line="85"/>
<source>Set your preferred language for UI</source>
<translation>選擇界所使用的語言</translation>
<translation>選擇界所使用的語言</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="95"/>
......@@ -564,7 +597,7 @@
<message>
<location filename="../../view/setting_interface.py" line="118"/>
<source>Open help page</source>
<translation>打開幫助頁</translation>
<translation>打開幫助頁</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="118"/>
......@@ -574,7 +607,7 @@
<message>
<location filename="../../view/setting_interface.py" line="118"/>
<source>Discover new features and learn useful tips about PyQt-Fluent-Widgets</source>
<translation>現新功能並了解有關 PyQt-Fluent-Widgets 的使用技巧</translation>
<translation>現新功能並了解有關 PyQt-Fluent-Widgets 的使用技巧</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="127"/>
......@@ -627,7 +660,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="50"/>
<source>A label with a ToolTip</source>
<translation>帶有工具提示的標</translation>
<translation>帶有工具提示的標</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="145"/>
......@@ -657,7 +690,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="149"/>
<source>Please wait patiently</source>
<translation>心急吃不了熱請耐心等待哦~</translation>
<translation>心急吃不了熱請耐心等待哦~</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="151"/>
......@@ -722,7 +755,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="74"/>
<source>My name is kira yoshikake, 33 years old. Living in the villa area northeast of duwangting, unmarried. I work in Guiyou chain store. Every day I have to work overtime until 8 p.m. to go home. I don&apos;t smoke. The wine is only for a taste. Sleep at 11 p.m. for 8 hours a day. Before I go to bed, I must drink a cup of warm milk, then do 20 minutes of soft exercise, get on the bed, and immediately fall asleep. Never leave fatigue and stress until the next day. Doctors say I&apos;m normal.</source>
<translation>我的名字叫吉良吉影33住在杜王町東北部的別墅區一帶未婚我在龜友連鎖店服務每天都要加班到晚上8點才能回家我不抽酒僅止於淺嘗晚上11點睡每天要睡足8個小時睡前我一定喝一杯溫牛奶然後做20分鐘的柔軟操上了床馬上熟睡一覺到天亮決不把疲勞和壓力留到第二天醫生都說我很正常</translation>
<translation>我的名字叫吉良吉影33住在杜王町東北部的別墅區一帶未婚我在龜友連鎖店服務每天都要加班到晚上8點才能回家我不抽酒僅止於淺嚐晚上11點睡每天要睡足8個小時睡前我一定喝一盃溫牛奶然後做20分鐘的柔軟操上了床馬上熟睡一覺到天亮決不把疲勞和壓力留到第二天醫生都説我很正常</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="156"/>
......@@ -732,7 +765,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="156"/>
<source>Believe in the spin, just keep believing!</source>
<translation>相信回旋吧管相信就是了</translation>
<translation>相信回旋吧管相信就是了</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="168"/>
......@@ -752,7 +785,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="57"/>
<source>The Anthem of man is the Anthem of courage.</source>
<translation>人類的贊歌就是勇氣的贊</translation>
<translation>人類的讚歌就是勇氣的讚</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="102"/>
......@@ -797,7 +830,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="201"/>
<source>Don&apos;t have any strange expectations of me.</source>
<translation>別對我抱有什奇怪的期待</translation>
<translation>別對我抱有什奇怪的期待</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="212"/>
......@@ -879,55 +912,60 @@
<context>
<name>Translator</name>
<message>
<location filename="../../common/translator.py" line="9"/>
<location filename="../../common/translator.py" line="18"/>
<source>Basic input</source>
<translation>基本輸入</translation>
</message>
<message>
<location filename="../../common/translator.py" line="10"/>
<location filename="../../common/translator.py" line="11"/>
<source>Menus</source>
<translation>菜單</translation>
</message>
<message>
<location filename="../../common/translator.py" line="11"/>
<location filename="../../common/translator.py" line="14"/>
<source>Dialogs</source>
<translation>對話框</translation>
</message>
<message>
<location filename="../../common/translator.py" line="12"/>
<location filename="../../common/translator.py" line="16"/>
<source>Material</source>
<translation>材料</translation>
</message>
<message>
<location filename="../../common/translator.py" line="13"/>
<location filename="../../common/translator.py" line="19"/>
<source>Status &amp; info</source>
<translation>狀態和信息</translation>
</message>
<message>
<location filename="../../common/translator.py" line="14"/>
<location filename="../../common/translator.py" line="15"/>
<source>Scrolling</source>
<translation>滾動</translation>
</message>
<message>
<location filename="../../common/translator.py" line="15"/>
<location filename="../../common/translator.py" line="13"/>
<source>Layout</source>
<translation></translation>
<translation></translation>
</message>
<message>
<location filename="../../common/translator.py" line="16"/>
<location filename="../../common/translator.py" line="9"/>
<source>Text</source>
<translation>文本</translation>
</message>
<message>
<location filename="../../common/translator.py" line="17"/>
<location filename="../../common/translator.py" line="12"/>
<source>Icons</source>
<translation>圖標</translation>
</message>
<message>
<location filename="../../common/translator.py" line="18"/>
<location filename="../../common/translator.py" line="10"/>
<source>View</source>
<translation>視圖</translation>
</message>
<message>
<location filename="../../common/translator.py" line="17"/>
<source>Date &amp; time</source>
<translation>日期和時間</translation>
</message>
</context>
<context>
<name>TreeFrame</name>
......@@ -944,7 +982,7 @@
<message>
<location filename="../../view/view_interface.py" line="60"/>
<source>Dio Brando</source>
<translation>迪奧·蘭度</translation>
<translation>迪奧·蘭度</translation>
</message>
<message>
<location filename="../../view/view_interface.py" line="60"/>
......@@ -972,7 +1010,7 @@
<message>
<location filename="../../view/view_interface.py" line="30"/>
<source>A TreeView with Multi-selection enabled</source>
<translation>啟用選框的樹狀組件</translation>
<translation>啟用選框的樹狀組件</translation>
</message>
</context>
</TS>
......@@ -124,6 +124,34 @@
<translation>可编辑的下拉框</translation>
</message>
</context>
<context>
<name>DateTimeInterface</name>
<message>
<location filename="../../view/date_time_interface.py" line="21"/>
<source>A simple DatePicker</source>
<translation>日期选择器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="27"/>
<source>A DatePicker in another format</source>
<translation>另一种格式的日期选择器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="34"/>
<source>A simple TimePicker</source>
<translation>时间选择器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="41"/>
<source>A TimePicker using a 24-hour clock</source>
<translation>24 小时制的时间选择器</translation>
</message>
<message>
<location filename="../../view/date_time_interface.py" line="48"/>
<source>A TimePicker with seconds column</source>
<translation>显示秒的时间选择器</translation>
</message>
</context>
<context>
<name>DialogInterface</name>
<message>
......@@ -270,75 +298,80 @@
<context>
<name>MainWindow</name>
<message>
<location filename="../../view/main_window.py" line="131"/>
<location filename="../../view/main_window.py" line="118"/>
<source>Home</source>
<translation>主页</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="137"/>
<location filename="../../view/main_window.py" line="124"/>
<source>Basic input</source>
<translation>基本输入</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="139"/>
<location filename="../../view/main_window.py" line="128"/>
<source>Dialogs</source>
<translation>对话框</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="141"/>
<location filename="../../view/main_window.py" line="130"/>
<source>Layout</source>
<translation>布局</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="145"/>
<location filename="../../view/main_window.py" line="134"/>
<source>Menus</source>
<translation>菜单</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="143"/>
<location filename="../../view/main_window.py" line="132"/>
<source>Material</source>
<translation>材料</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="147"/>
<location filename="../../view/main_window.py" line="136"/>
<source>Scrolling</source>
<translation>滚动</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="149"/>
<location filename="../../view/main_window.py" line="138"/>
<source>Status &amp; info</source>
<translation>状态和信息</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="208"/>
<location filename="../../view/main_window.py" line="198"/>
<source>This is a help message</source>
<translation>一条友善的提示</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="208"/>
<location filename="../../view/main_window.py" line="198"/>
<source>You clicked a customized navigation widget. You can add more custom widgets by calling `NavigationInterface.addWidget()` 😉</source>
<translation>你点击了一个自定义的导航项你可以通过 `NavigationInterface.addWidget()` 添加更多的自定义导航项</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="151"/>
<location filename="../../view/main_window.py" line="140"/>
<source>Text</source>
<translation>文本</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="133"/>
<location filename="../../view/main_window.py" line="120"/>
<source>Icons</source>
<translation>图标</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="153"/>
<location filename="../../view/main_window.py" line="142"/>
<source>View</source>
<translation>视图</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="163"/>
<location filename="../../view/main_window.py" line="152"/>
<source>Settings</source>
<translation>设置</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="126"/>
<source>Date &amp; time</source>
<translation>日期和时间</translation>
</message>
</context>
<context>
<name>MaterialInterface</name>
......@@ -879,55 +912,60 @@
<context>
<name>Translator</name>
<message>
<location filename="../../common/translator.py" line="9"/>
<location filename="../../common/translator.py" line="18"/>
<source>Basic input</source>
<translation>基本输入</translation>
</message>
<message>
<location filename="../../common/translator.py" line="10"/>
<location filename="../../common/translator.py" line="11"/>
<source>Menus</source>
<translation>菜单</translation>
</message>
<message>
<location filename="../../common/translator.py" line="11"/>
<location filename="../../common/translator.py" line="14"/>
<source>Dialogs</source>
<translation>对话框</translation>
</message>
<message>
<location filename="../../common/translator.py" line="12"/>
<location filename="../../common/translator.py" line="16"/>
<source>Material</source>
<translation>材料</translation>
</message>
<message>
<location filename="../../common/translator.py" line="13"/>
<location filename="../../common/translator.py" line="19"/>
<source>Status &amp; info</source>
<translation>状态和信息</translation>
</message>
<message>
<location filename="../../common/translator.py" line="14"/>
<location filename="../../common/translator.py" line="15"/>
<source>Scrolling</source>
<translation>滚动</translation>
</message>
<message>
<location filename="../../common/translator.py" line="15"/>
<location filename="../../common/translator.py" line="13"/>
<source>Layout</source>
<translation>布局</translation>
</message>
<message>
<location filename="../../common/translator.py" line="16"/>
<location filename="../../common/translator.py" line="9"/>
<source>Text</source>
<translation>文本</translation>
</message>
<message>
<location filename="../../common/translator.py" line="17"/>
<location filename="../../common/translator.py" line="12"/>
<source>Icons</source>
<translation>图标</translation>
</message>
<message>
<location filename="../../common/translator.py" line="18"/>
<location filename="../../common/translator.py" line="10"/>
<source>View</source>
<translation>视图</translation>
</message>
<message>
<location filename="../../common/translator.py" line="17"/>
<source>Date &amp; time</source>
<translation>日期和时间</translation>
</message>
</context>
<context>
<name>TreeFrame</name>
......
......@@ -62,6 +62,69 @@
<translation>取消</translation>
</message>
</context>
<context>
<name>DatePicker</name>
<message>
<source>month</source>
<translation></translation>
</message>
<message>
<source>day</source>
<translation></translation>
</message>
<message>
<source>year</source>
<translation></translation>
</message>
<message>
<source>January</source>
<translation>一月</translation>
</message>
<message>
<source>February</source>
<translation>二月</translation>
</message>
<message>
<source>March</source>
<translation>三月</translation>
</message>
<message>
<source>April</source>
<translation>四月</translation>
</message>
<message>
<source>May</source>
<translation>五月</translation>
</message>
<message>
<source>June</source>
<translation>六月</translation>
</message>
<message>
<source>July</source>
<translation>七月</translation>
</message>
<message>
<source>August</source>
<translation>八月</translation>
</message>
<message>
<source>September</source>
<translation>九月</translation>
</message>
<message>
<source>October</source>
<translation>十月</translation>
</message>
<message>
<source>November</source>
<translation>十一月</translation>
</message>
<message>
<source>December</source>
<translation>十二月</translation>
</message>
</context>
<context>
<name>FolderListDialog</name>
<message>
......@@ -82,7 +145,7 @@
</message>
<message>
<source> folder and remove it from the list, the folder will no longer appear in the list, but will not be deleted.</source>
<translation> 文件夾從列錶中移除則該文件夾不會再出現在列錶但不會被刪除</translation>
<translation> 文件夾從列表中移除則該文件夾不會再出現在列表但不會被刪除</translation>
</message>
</context>
<context>
......@@ -138,7 +201,7 @@
</message>
<message>
<source> folder and remove it from the list, the folder will no longer appear in the list, but will not be deleted.</source>
<translation> 文件夾從列錶中移除則該文件夾不會再出現在列錶但不會被刪除</translation>
<translation> 文件夾從列表中移除則該文件夾不會再出現在列表但不會被刪除</translation>
</message>
</context>
<context>
......@@ -149,11 +212,11 @@
</message>
<message>
<source>Copy</source>
<translation>復制</translation>
<translation>複製</translation>
</message>
<message>
<source>Paste</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Cancel</source>
......@@ -172,11 +235,11 @@
</message>
<message>
<source>Copy</source>
<translation>復制</translation>
<translation>複製</translation>
</message>
<message>
<source>Paste</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Cancel</source>
......@@ -187,4 +250,42 @@
<translation>全選</translation>
</message>
</context>
<context>
<name>TimePicker</name>
<message>
<source>hour</source>
<translation></translation>
</message>
<message>
<source>minute</source>
<translation></translation>
</message>
<message>
<source>second</source>
<translation></translation>
</message>
<message>
<source>AM</source>
<translation>AM</translation>
</message>
<message>
<source>PM</source>
<translation>PM</translation>
</message>
</context>
<context>
<name>AMTimePicker</name>
<message>
<source>hour</source>
<translation></translation>
</message>
<message>
<source>minute</source>
<translation></translation>
</message>
<message>
<source>second</source>
<translation></translation>
</message>
</context>
</TS>
\ No newline at end of file
......@@ -62,6 +62,69 @@
<translation>取消</translation>
</message>
</context>
<context>
<name>DatePicker</name>
<message>
<source>month</source>
<translation></translation>
</message>
<message>
<source>day</source>
<translation></translation>
</message>
<message>
<source>year</source>
<translation></translation>
</message>
<message>
<source>January</source>
<translation>一月</translation>
</message>
<message>
<source>February</source>
<translation>二月</translation>
</message>
<message>
<source>March</source>
<translation>三月</translation>
</message>
<message>
<source>April</source>
<translation>四月</translation>
</message>
<message>
<source>May</source>
<translation>五月</translation>
</message>
<message>
<source>June</source>
<translation>六月</translation>
</message>
<message>
<source>July</source>
<translation>七月</translation>
</message>
<message>
<source>August</source>
<translation>八月</translation>
</message>
<message>
<source>September</source>
<translation>九月</translation>
</message>
<message>
<source>October</source>
<translation>十月</translation>
</message>
<message>
<source>November</source>
<translation>十一月</translation>
</message>
<message>
<source>December</source>
<translation>十二月</translation>
</message>
</context>
<context>
<name>FolderListDialog</name>
<message>
......@@ -187,4 +250,42 @@
<translation>全选</translation>
</message>
</context>
<context>
<name>TimePicker</name>
<message>
<source>hour</source>
<translation></translation>
</message>
<message>
<source>minute</source>
<translation></translation>
</message>
<message>
<source>second</source>
<translation></translation>
</message>
<message>
<source>AM</source>
<translation>AM</translation>
</message>
<message>
<source>PM</source>
<translation>PM</translation>
</message>
</context>
<context>
<name>AMTimePicker</name>
<message>
<source>hour</source>
<translation></translation>
</message>
<message>
<source>minute</source>
<translation></translation>
</message>
<message>
<source>second</source>
<translation></translation>
</message>
</context>
</TS>
\ No newline at end of file
# coding:utf-8
from PyQt5.QtCore import Qt
from qfluentwidgets import DatePicker, TimePicker, AMTimePicker
from .gallery_interface import GalleryInterface
from ..common.translator import Translator
class DateTimeInterface(GalleryInterface):
""" Date time interface """
def __init__(self, parent=None):
t = Translator()
super().__init__(
title=t.dateTime,
subtitle='qfluentwidgets.components.date_time',
parent=parent
)
# date picker
self.addExampleCard(
title=self.tr('A simple DatePicker'),
widget=DatePicker(self),
sourcePath='https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/date_time/demo.py'
)
self.addExampleCard(
title=self.tr('A DatePicker in another format'),
widget=DatePicker(self, DatePicker.YYYY_MM_DD),
sourcePath='https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/date_time/demo.py'
)
# AM/PM time picker
self.addExampleCard(
title=self.tr('A simple TimePicker'),
widget=AMTimePicker(self),
sourcePath='https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/date_time/demo.py'
)
# 24 hours time picker
self.addExampleCard(
title=self.tr('A TimePicker using a 24-hour clock'),
widget=TimePicker(self),
sourcePath='https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/date_time/demo.py'
)
# 24 hours time picker
self.addExampleCard(
title=self.tr('A TimePicker with seconds column'),
widget=TimePicker(self, True),
sourcePath='https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/date_time/demo.py'
)
......@@ -113,6 +113,7 @@ class HomeInterface(ScrollArea):
def loadSamples(self):
""" load samples """
# basic input samples
basicInputView = SampleCardView(
self.tr("Basic input samples"), self.view)
basicInputView.addSampleCard(
......@@ -164,6 +165,26 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(basicInputView)
# date time samples
dateTimeView = SampleCardView(self.tr('Dialog samples'), self.view)
dateTimeView.addSampleCard(
icon=":/gallery/images/controls/DatePicker.png",
title="DatePicker",
content=self.tr("A control that lets a user pick a date value."),
routeKey="dateTimeInterface",
index=0
)
dateTimeView.addSampleCard(
icon=":/gallery/images/controls/TimePicker.png",
title="TimePicker",
content=self.tr(
"A configurable control that lets a user pick a time value."),
routeKey="dateTimeInterface",
index=2
)
self.vBoxLayout.addWidget(dateTimeView)
# dialog samples
dialogView = SampleCardView(self.tr('Dialog samples'), self.view)
dialogView.addSampleCard(
icon=":/gallery/images/controls/Flyout.png",
......@@ -188,6 +209,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(dialogView)
# layout samples
layoutView = SampleCardView(self.tr('Layout samples'), self.view)
layoutView.addSampleCard(
icon=":/gallery/images/controls/Grid.png",
......@@ -199,6 +221,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(layoutView)
# material samples
materialView = SampleCardView(self.tr('Material samples'), self.view)
materialView.addSampleCard(
icon=":/gallery/images/controls/Acrylic.png",
......@@ -210,6 +233,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(materialView)
# menu samples
menuView = SampleCardView(self.tr('Menu samples'), self.view)
menuView.addSampleCard(
icon=":/gallery/images/controls/MenuFlyout.png",
......@@ -221,6 +245,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(menuView)
# scroll samples
scrollView = SampleCardView(self.tr('Scrolling samples'), self.view)
scrollView.addSampleCard(
icon=":/gallery/images/controls/ScrollViewer.png",
......@@ -232,6 +257,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(scrollView)
# state info samples
stateInfoView = SampleCardView(self.tr('Scrolling samples'), self.view)
stateInfoView.addSampleCard(
icon=":/gallery/images/controls/ProgressRing.png",
......@@ -259,6 +285,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(stateInfoView)
# text samples
textView = SampleCardView(self.tr('Text samples'), self.view)
textView.addSampleCard(
icon=":/gallery/images/controls/TextBox.png",
......@@ -285,6 +312,7 @@ class HomeInterface(ScrollArea):
)
self.vBoxLayout.addWidget(textView)
# view samples
collectionView = SampleCardView(self.tr('View samples'), self.view)
collectionView.addSampleCard(
icon=":/gallery/images/controls/TreeView.png",
......
......@@ -13,6 +13,7 @@ from .title_bar import CustomTitleBar
from .gallery_interface import GalleryInterface
from .home_interface import HomeInterface
from .basic_input_interface import BasicInputInterface
from .date_time_interface import DateTimeInterface
from .dialog_interface import DialogInterface
from .layout_interface import LayoutInterface
from .icon_interface import IconInterface
......@@ -77,6 +78,7 @@ class MainWindow(FramelessWindow):
self.homeInterface = HomeInterface(self)
self.iconInterface = IconInterface(self)
self.basicInputInterface = BasicInputInterface(self)
self.dateTimeInterface = DateTimeInterface(self)
self.dialogInterface = DialogInterface(self)
self.layoutInterface = LayoutInterface(self)
self.menuInterface = MenuInterface(self)
......@@ -87,19 +89,6 @@ class MainWindow(FramelessWindow):
self.textInterface = TextInterface(self)
self.viewInterface = ViewInterface(self)
self.stackWidget.addWidget(self.homeInterface)
self.stackWidget.addWidget(self.iconInterface)
self.stackWidget.addWidget(self.basicInputInterface)
self.stackWidget.addWidget(self.dialogInterface)
self.stackWidget.addWidget(self.layoutInterface)
self.stackWidget.addWidget(self.materialInterface)
self.stackWidget.addWidget(self.menuInterface)
self.stackWidget.addWidget(self.scrollInterface)
self.stackWidget.addWidget(self.statusInfoInterface)
self.stackWidget.addWidget(self.settingInterface)
self.stackWidget.addWidget(self.textInterface)
self.stackWidget.addWidget(self.viewInterface)
# initialize layout
self.initLayout()
......@@ -125,8 +114,6 @@ class MainWindow(FramelessWindow):
self.titleBar.raise_()
def initNavigation(self):
self.settingInterface.setObjectName('settingsInterface')
# add navigation items
self.addSubInterface(
self.homeInterface, 'homeInterface', FIF.HOME, self.tr('Home'), NavigationItemPosition.TOP)
......@@ -136,6 +123,8 @@ class MainWindow(FramelessWindow):
self.addSubInterface(
self.basicInputInterface, 'basicInputInterface', FIF.CHECKBOX, self.tr('Basic input'))
self.addSubInterface(
self.dateTimeInterface, 'dateTimeInterface', FIF.DATE_TIME, self.tr('Date & time'))
self.addSubInterface(
self.dialogInterface, 'dialogInterface', FIF.MESSAGE, self.tr('Dialogs'))
self.addSubInterface(
......@@ -173,9 +162,10 @@ class MainWindow(FramelessWindow):
self.homeInterface.objectName())
self.stackWidget.setCurrentIndex(0)
def addSubInterface(self, interface: QWidget, objectName: str, icon, text:str, position=NavigationItemPosition.SCROLL):
def addSubInterface(self, interface: QWidget, objectName: str, icon, text: str, position=NavigationItemPosition.SCROLL):
""" add sub interface """
interface.setObjectName(objectName)
self.stackWidget.addWidget(interface)
self.navigationInterface.addItem(
routeKey=objectName,
icon=icon,
......
......@@ -12,6 +12,7 @@ SOURCES += app/view/main_window.py \
app/view/text_interface.py \
app/view/icon_interface.py \
app/view/view_interface.py \
app/view/date_time_interface.py \
TRANSLATIONS += app/resource/i18n/gallery_zh.ts \
app/resource/i18n/gallery_hk.ts
# coding:utf-8
import sys
from PyQt5.QtCore import Qt, QTime
from PyQt5.QtCore import QDate, Qt, QTime
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
from qfluentwidgets import TimePicker, AMTimePicker
from qfluentwidgets import TimePicker, AMTimePicker, DatePicker
class Demo(QWidget):
......@@ -14,18 +14,26 @@ class Demo(QWidget):
super().__init__()
self.vBoxLayout = QVBoxLayout(self)
self.picker0 = DatePicker(self, DatePicker.YYYY_MM_DD)
self.picker1 = AMTimePicker(self)
self.picker2 = TimePicker(self)
self.picker3 = TimePicker(self, True)
self.picker0.dateChanged.connect(lambda t: print(t.toString()))
self.picker1.timeChanged.connect(lambda t: print(t.toString()))
self.picker2.timeChanged.connect(lambda t: print(t.toString()))
self.picker3.timeChanged.connect(lambda t: print(t.toString()))
# set current time
# set current date/time
# self.picker0.setDate(QDate.currentDate())
# self.picker1.setTime(QTime(13, 15))
# self.picker2.setTime(QTime(13, 15))
self.resize(500, 500)
self.vBoxLayout.addWidget(self.picker0, 0, Qt.AlignHCenter)
self.vBoxLayout.addWidget(self.picker1, 0, Qt.AlignHCenter)
self.vBoxLayout.addWidget(self.picker2, 0, Qt.AlignHCenter)
self.vBoxLayout.addWidget(self.picker3, 0, Qt.AlignHCenter)
if __name__ == '__main__':
......
......@@ -12,7 +12,7 @@ Examples are available at https://github.com/zhiyiYo/PyQt-Fluent-Widgets/tree/ma
:license: GPLv3, see LICENSE for more details.
"""
__version__ = "0.6.9"
__version__ = "0.7.0"
from .components import *
from .common import *
......
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048"
xml:space="preserve"><path fill="#000000" d="M726.4 1774.93 q18.13 36.27 38.93 70.4 q20.8 34.13 45.34 66.13 l-409.6 0 q-80 0 -153.07 -32.54 q-73.07 -32.53 -128 -87.47 q-54.93 -54.94 -87.47 -128 q-32.53 -73.07 -32.53 -153.07 l0 -1109.33 q0 -80 32.53 -153.07 q32.53 -73.07 87.47 -128 q54.93 -54.93 128 -87.47 q73.07 -32.53 153.07 -32.53 l1109.33 0 q80 0 153.07 32.53 q73.06 32.53 128 87.47 q54.93 54.93 87.47 128 q32.54 73.07 32.54 153.07 l0 409.6 q-32 -24.54 -66.13 -45.34 q-34.13 -20.8 -70.4 -38.93 l0 -180.27 l-1638.4 0 l0 961.07 q0 55.47 22.4 104 q22.4 48.53 59.74 84.8 q37.33 36.27 86.94 57.6 q49.6 21.33 104 21.33 l316.8 0 ZM404.27 136.53 q-54.4 0 -103.47 22.4 q-49.07 22.4 -85.34 59.74 q-36.26 37.33 -57.6 86.94 q-21.34 49.6 -21.34 104 l1638.4 0 l0 -5.33 q0 -53.34 -21.87 -101.87 q-21.87 -48.53 -58.66 -85.33 q-36.8 -36.8 -85.34 -58.67 q-48.54 -21.87 -101.87 -21.87 l-1102.93 0 ZM2048 1433.6 q0 126.93 -48.53 238.93 q-48.54 112 -131.74 195.2 q-83.2 83.2 -195.2 131.74 q-112 48.53 -238.93 48.53 q-128 0 -240 -48 q-112 -48 -195.2 -131.2 q-83.2 -83.2 -131.2 -195.2 q-48 -112 -48 -240 q0 -126.93 48.53 -238.93 q48.53 -112 131.74 -195.2 q83.2 -83.2 195.2 -131.74 q112 -48.53 238.93 -48.53 q84.27 0 162.67 21.87 q78.4 21.86 146.66 61.86 q68.27 40 124.8 96.53 q56.53 56.54 96.53 124.8 q40 68.27 61.87 146.66 q21.87 78.4 21.87 162.67 ZM1638.4 1501.87 q27.73 0 48 -20.27 q20.27 -20.27 20.27 -48 q0 -27.73 -20.27 -48 q-20.27 -20.27 -48 -20.27 l-136.53 0 l0 -204.8 q0 -27.73 -20.27 -48 q-20.27 -20.26 -48 -20.26 q-27.73 0 -48 20.26 q-20.27 20.27 -20.27 48 l0 273.07 q0 27.73 20.27 48 q20.27 20.27 48 20.27 l204.8 0 Z"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg id="" width="16" height="16" style="width:16px;height:16px;" version="1.1"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2048 2048" enable-background="new 0 0 2048 2048"
xml:space="preserve"><path fill="#ffffff" d="M726.4 1774.93 q18.13 36.27 38.93 70.4 q20.8 34.13 45.34 66.13 l-409.6 0 q-80 0 -153.07 -32.54 q-73.07 -32.53 -128 -87.47 q-54.93 -54.94 -87.47 -128 q-32.53 -73.07 -32.53 -153.07 l0 -1109.33 q0 -80 32.53 -153.07 q32.53 -73.07 87.47 -128 q54.93 -54.93 128 -87.47 q73.07 -32.53 153.07 -32.53 l1109.33 0 q80 0 153.07 32.53 q73.06 32.53 128 87.47 q54.93 54.93 87.47 128 q32.54 73.07 32.54 153.07 l0 409.6 q-32 -24.54 -66.13 -45.34 q-34.13 -20.8 -70.4 -38.93 l0 -180.27 l-1638.4 0 l0 961.07 q0 55.47 22.4 104 q22.4 48.53 59.74 84.8 q37.33 36.27 86.94 57.6 q49.6 21.33 104 21.33 l316.8 0 ZM404.27 136.53 q-54.4 0 -103.47 22.4 q-49.07 22.4 -85.34 59.74 q-36.26 37.33 -57.6 86.94 q-21.34 49.6 -21.34 104 l1638.4 0 l0 -5.33 q0 -53.34 -21.87 -101.87 q-21.87 -48.53 -58.66 -85.33 q-36.8 -36.8 -85.34 -58.67 q-48.54 -21.87 -101.87 -21.87 l-1102.93 0 ZM2048 1433.6 q0 126.93 -48.53 238.93 q-48.54 112 -131.74 195.2 q-83.2 83.2 -195.2 131.74 q-112 48.53 -238.93 48.53 q-128 0 -240 -48 q-112 -48 -195.2 -131.2 q-83.2 -83.2 -131.2 -195.2 q-48 -112 -48 -240 q0 -126.93 48.53 -238.93 q48.53 -112 131.74 -195.2 q83.2 -83.2 195.2 -131.74 q112 -48.53 238.93 -48.53 q84.27 0 162.67 21.87 q78.4 21.86 146.66 61.86 q68.27 40 124.8 96.53 q56.53 56.54 96.53 124.8 q40 68.27 61.87 146.66 q21.87 78.4 21.87 162.67 ZM1638.4 1501.87 q27.73 0 48 -20.27 q20.27 -20.27 20.27 -48 q0 -27.73 -20.27 -48 q-20.27 -20.27 -48 -20.27 l-136.53 0 l0 -204.8 q0 -27.73 -20.27 -48 q-20.27 -20.26 -48 -20.26 q-27.73 0 -48 20.26 q-20.27 20.27 -20.27 48 l0 273.07 q0 27.73 20.27 48 q20.27 20.27 48 20.27 l204.8 0 Z"/></svg>
\ No newline at end of file
......@@ -72,6 +72,8 @@ PickerBase:pressed {
background-color: transparent;
border: none;
outline: none;
padding-left: 10px;
padding-right: 10px;
}
#pickerButton[hasBorder=true] {
......@@ -91,12 +93,14 @@ PickerBase:pressed {
color: rgba(255, 255, 255, 0.786);
}
#pickerButton[align="center"] {
text-align: center;
}
#pickerButton[align="left"] {
text-align: left;
padding-left: 10px;
}
#pickerButton[align="right"] {
text-align: right;
padding-right: 10px;
}
\ No newline at end of file
......@@ -71,6 +71,8 @@ PickerBase:pressed {
background-color: transparent;
border: none;
outline: none;
padding-left: 10px;
padding-right: 10px;
}
#pickerButton[hasBorder=true] {
......@@ -90,12 +92,14 @@ PickerBase:pressed {
color: rgba(0, 0, 0, 0.6);
}
#pickerButton[align="center"] {
text-align: center;
}
#pickerButton[align="left"] {
text-align: left;
padding-left: 10px;
}
#pickerButton[align="right"] {
text-align: right;
padding-right: 10px;
}
此差异已折叠。
......@@ -161,6 +161,8 @@
<file>images/icons/Delete_white.svg</file>
<file>images/icons/Accept_black.svg</file>
<file>images/icons/Accept_white.svg</file>
<file>images/icons/DateTime_black.svg</file>
<file>images/icons/DateTime_white.svg</file>
<file>images/acrylic/noise.png</file>
<file>images/folder_list_dialog/Close_white.png</file>
<file>images/folder_list_dialog/Close_black.png</file>
......
......@@ -266,6 +266,7 @@ class FluentIcon(FluentIconBase, Enum):
LANGUAGE = "Language"
DOWNLOAD = "Download"
QUESTION = "Question"
DATE_TIME = "DateTime"
SEND_FILL = "SendFill"
COMPLETED = "Completed"
CONSTRACT = "Constract"
......
from .time_picker import TimePicker, AMTimePicker
from .picker_base import PickerBase, PickerPanel
\ No newline at end of file
from .date_picker import DatePickerBase, DatePicker
from .picker_base import PickerBase, PickerPanel
from .time_picker import TimePicker, AMTimePicker
\ No newline at end of file
# coding:utf-8
from PyQt5.QtGui import QFontMetrics, QFont
from PyQt5.QtCore import Qt, pyqtSignal, QDate, QCalendar
from .picker_base import PickerBase, PickerPanel
class DatePickerBase(PickerBase):
""" Date picker base class """
dateChanged = pyqtSignal(QDate)
def __init__(self, parent=None):
super().__init__(parent)
self.date = QDate()
self.calendar = QCalendar()
def setDate(self, date: QDate):
""" set current date """
raise NotImplementedError
class DatePicker(DatePickerBase):
""" Date picker """
MM_DD_YYYY = 0
YYYY_MM_DD = 1
def __init__(self, parent=None, format=MM_DD_YYYY):
"""
Parameters
----------
parent: QWidget
parent widget
format: int
the format of date, could be `DatePicker.MM_DD_YYYY` or `DatePicker.YYYY_MM_DD`
"""
super().__init__(parent=parent)
self.months = [
self.tr('January'), self.tr('February'), self.tr('March'),
self.tr('April'), self.tr('May'), self.tr('June'),
self.tr('July'), self.tr('August'), self.tr('September'),
self.tr('October'), self.tr('November'), self.tr('December')
]
self.setDateFormat(format)
def setDateFormat(self, format: int):
""" set the format of date
Parameters
----------
format: int
the format of date, could be `DatePicker.MM_DD_YYYY` or `DatePicker.YYYY_MM_DD`
"""
self.clearColumns()
y = QDate.currentDate().year()
font = QFont()
font.setFamilies(['Segoe UI', 'Microsoft YaHei'])
font.setPixelSize(14)
fm = QFontMetrics(font)
w = max(fm.width(i) for i in self.months) + 69
if format == self.MM_DD_YYYY:
self.monthIndex = 0
self.dayIndex = 1
self.yearIndex = 2
self.addColumn(self.tr('month'), self.months, w, Qt.AlignLeft)
self.addColumn(self.tr('day'), range(1, 32), 80)
self.addColumn(self.tr('year'), range(y-100, y+101), 80)
elif format == self.YYYY_MM_DD:
self.yearIndex = 0
self.monthIndex = 1
self.dayIndex = 2
self.addColumn(self.tr('year'), range(y-100, y+101), 80)
self.addColumn(self.tr('month'), self.months, w)
self.addColumn(self.tr('day'), range(1, 32), 80)
# initialize date
date = self.date.currentDate()
self.columns[self.monthIndex].value = self.months[date.month() - 1]
self.columns[self.dayIndex].value = date.day()
self.columns[self.yearIndex].value = date.year()
def _onColumnValueChanged(self, panel: PickerPanel, index, value):
if index == self.dayIndex:
return
# get days number in month
month = panel.columnValue(self.monthIndex)
month = self.months.index(month) + 1
year = int(panel.columnValue(self.yearIndex))
days = self.calendar.daysInMonth(month, year)
# update days
c = panel.column(self.dayIndex)
day = c.currentItem().text()
c.setItems(range(1, days + 1))
c.setSelectedItem(day)
self.columns[self.dayIndex].items = list(range(1, days + 1))
def _onConfirmed(self, value: list):
month = self.months.index(value[self.monthIndex]) + 1
date = QDate(int(value[self.yearIndex]), month, int(value[self.dayIndex]))
od = self.date
self.setDate(date)
if od != date:
self.dateChanged.emit(date)
def setDate(self, date: QDate):
if not date.isValid() or date.isNull():
return
self.date = date
self.setColumnValue(self.monthIndex, self.months[date.month() - 1])
self.setColumnValue(self.dayIndex, date.day())
self.setColumnValue(self.yearIndex, date.year())
self.columns[self.dayIndex].items = list(range(1, date.daysInMonth() + 1))
\ No newline at end of file
......@@ -92,7 +92,16 @@ class PickerColumn:
self.items = items
self.width = width
self.align = align
self.value = None # type: str
self._value = None # type: str
self.isVisible = True
@property
def value(self):
return self._value
@value.setter
def value(self, v):
self._value = str(v)
class PickerBase(QPushButton):
......@@ -148,18 +157,40 @@ class PickerBase(QPushButton):
self.hBoxLayout.addWidget(button, 0, Qt.AlignLeft)
self.buttons.append(button)
if align == Qt.AlignLeft:
button.setProperty('align', 'left')
elif align == Qt.AlignRight:
button.setProperty('align', 'right')
self._setButtonAlignment(button, align)
# update the style of buttons
for btn in self.buttons[:-1]:
btn.setProperty('hasBorder', True)
btn.setStyle(QApplication.style())
def _setButtonAlignment(self, button: QPushButton, align=Qt.AlignCenter):
""" set the text alignment of button """
if align == Qt.AlignLeft:
button.setProperty('align', 'left')
elif align == Qt.AlignRight:
button.setProperty('align', 'right')
else:
button.setProperty('align', 'center')
def setColumnAlignment(self, index: int, align=Qt.AlignCenter):
""" set the text alignment of specified column """
if not 0 <= index < len(self.columns):
return
self.columns[index].align = align
self._setButtonAlignment(self.buttons[index], align)
def setColumnVisible(self, index: int, isVisible: bool):
""" set the text alignment of specified column """
if not 0 <= index < len(self.columns):
return
self.columns[index].isVisible = isVisible
self.buttons[index].setVisible(isVisible)
def value(self):
return [c.value for c in self.columns]
return [c.value for c in self.columns if c.isVisible]
def setColumnValue(self, index: int, value):
if not 0 <= index < len(self.columns):
......@@ -170,6 +201,48 @@ class PickerBase(QPushButton):
self.buttons[index].setText(value)
self._setButtonProperty('hasValue', True)
def setColumn(self, index: int, name: str, items: Iterable, width: int, align=Qt.AlignCenter):
""" set column
Parameters
----------
index: int
the index of column
name: str
the name of column
items: Iterable
the items of column
width: int
the width of column
align: Qt.AlignmentFlag
the text alignment of button
"""
if not 0 <= index < len(self.columns):
return
column = self.columns[index]
self.columnMap.pop(column.name)
column = PickerColumn(name, items, width, align)
self.columns[index] = column
self.columnMap[name] = column
self.buttons[index].setText(name)
self.buttons[index].setFixedWidth(width)
self._setButtonAlignment(self.buttons[index], align)
def clearColumns(self):
""" clear columns """
self.columns.clear()
self.columnMap.clear()
while self.buttons:
btn = self.buttons.pop()
btn.deleteLater()
def enterEvent(self, e):
self._setButtonProperty('enter', True)
......@@ -194,21 +267,31 @@ class PickerBase(QPushButton):
""" show panel """
panel = PickerPanel(self)
for column in self.columns:
panel.addColumn(column.items, column.width, column.align)
if column.isVisible:
panel.addColumn(column.items, column.width, column.align)
panel.setValue(self.value())
panel.confirmed.connect(self._onConfirmed)
panel.columnValueChanged.connect(
lambda i, v: self._onColumnValueChanged(panel, i, v))
panel.exec(self.mapToGlobal(QPoint(0, -37*4)))
def _onConfirmed(self, value: list):
for i, v in enumerate(value):
self.setColumnValue(i, v)
def _onColumnValueChanged(self, panel, index: int, value: str):
""" column value changed slot """
pass
class PickerPanel(QWidget):
""" picker panel """
confirmed = pyqtSignal(list)
columnValueChanged = pyqtSignal(int, str)
def __init__(self, parent=None):
super().__init__(parent=parent)
......@@ -296,6 +379,10 @@ class PickerPanel(QWidget):
w = CycleListWidget(items, QSize(width, self.itemHeight), align, self)
w.vScrollBar.valueChanged.connect(self.itemMaskWidget.update)
N = len(self.listWidgets)
w.currentItemChanged.connect(
lambda i, n=N: self.columnValueChanged.emit(n, i.text()))
self.listWidgets.append(w)
self.listLayout.addWidget(w)
......@@ -305,14 +392,37 @@ class PickerPanel(QWidget):
self.itemMaskWidget.move(m.left()+2, m.top() + 148)
def value(self):
""" return the value of columns """
return [i.currentItem().text() for i in self.listWidgets]
def setValue(self, value: list):
""" set the value of columns """
if len(value) != len(self.listWidgets):
return
for v, w in zip(value, self.listWidgets):
w.setSelectedItem(v)
def columnValue(self, index: int) -> str:
""" return the value of specified column """
if not 0 <= index < len(self.listWidgets):
return
return self.listWidgets[index].currentItem().text()
def setColumnValue(self, index: int, value: str):
""" set the value of specified column """
if not 0 <= index < len(self.listWidgets):
return
self.listWidgets[index].setSelectedItem(value)
def column(self, index: int):
""" return the list widget of specified column """
return self.listWidgets[index]
def exec(self, pos, ani=True):
""" show menu
""" show panel
Parameters
----------
......@@ -325,16 +435,16 @@ class PickerPanel(QWidget):
if self.isVisible():
return
# show before running animation, or the height calculation will be wrong
self.show()
rect = QApplication.screenAt(QCursor.pos()).availableGeometry()
w, h = self.width() + 5, self.height() + 5
w, h = self.width() + 5, self.height()
pos.setX(
min(pos.x() - self.layout().contentsMargins().left(), rect.right() - w))
pos.setY(max(rect.top(), min(pos.y() - 4, rect.bottom() - h)))
pos.setY(max(rect.top(), min(pos.y() - 4, rect.bottom() - h + 5)))
self.move(pos)
# show before running animation, or the height calculation will be wrong
self.show()
if not ani:
return
......
......@@ -13,14 +13,10 @@ class TimePickerBase(PickerBase):
timeChanged = pyqtSignal(QTime)
def __init__(self, parent=None):
def __init__(self, parent=None, showSeconds=False):
super().__init__(parent=parent)
self.showSeconds = showSeconds
self.time = QTime()
self._addColumns()
def _addColumns(self):
""" add column to time picker """
raise NotImplementedError
def setTime(self, time: QTime):
""" set current time
......@@ -32,15 +28,27 @@ class TimePickerBase(PickerBase):
"""
raise NotImplementedError
def setSecondVisible(self, isVisible: bool):
""" set the visibility of seconds column """
raise NotImplementedError
class TimePicker(TimePickerBase):
""" 24 hours time picker """
def _addColumns(self):
self.addColumn(self.tr('hour'), range(0, 24), 120)
def __init__(self, parent=None, showSeconds=False):
super().__init__(parent, showSeconds)
# add hour column
w = 80 if showSeconds else 120
self.addColumn(self.tr('hour'), range(0, 24), w)
# add minute column
minute = [str(i).zfill(2) for i in range(0, 60)]
self.addColumn(self.tr('minute'), minute, 120)
self.addColumn(self.tr('minute'), minute, w)
# add seconds column
self.addColumn(self.tr('second'), minute, w)
self.setColumnVisible(2, showSeconds)
def setTime(self, time):
if not time.isValid() or time.isNull():
......@@ -49,11 +57,20 @@ class TimePicker(TimePickerBase):
self.time = time
self.setColumnValue(0, time.hour())
self.setColumnValue(1, str(time.minute()).zfill(2))
self.setColumnValue(2, str(time.second()).zfill(2))
def setSecondVisible(self, isVisible: bool):
self.setColumnVisible(2, isVisible)
w = 80 if isVisible else 120
for column, button in zip(self.columns, self.buttons):
button.setFixedWidth(w)
column.width = w
def _onConfirmed(self, value: list):
super()._onConfirmed(value)
h, m = int(value[0]), int(value[1])
time = QTime(h, m)
s = 0 if len(value) == 2 else int(value[2])
time = QTime(h, m, s)
ot = self.time
self.setTime(time)
......@@ -64,16 +81,27 @@ class TimePicker(TimePickerBase):
class AMTimePicker(TimePickerBase):
""" AM/PM time picker """
def __init__(self, parent=None):
super().__init__(parent)
def __init__(self, parent=None, showSeconds=False):
super().__init__(parent, showSeconds)
self.AM = self.tr('AM')
self.PM = self.tr('PM')
def _addColumns(self):
# add hour column
self.addColumn(self.tr('hour'), range(1, 13), 80)
# add minute column
minute = [str(i).zfill(2) for i in range(0, 60)]
self.addColumn(self.tr('minute'), minute, 80)
self.addColumn(self.tr('AM'), [self.tr('AM'), self.tr('PM')], 80)
# add second column
self.addColumn(self.tr('second'), minute, 80)
self.setColumnVisible(2, showSeconds)
# add AM/PM column
self.addColumn(self.AM, [self.AM, self.PM], 80)
def setSecondVisible(self, isVisible: bool):
self.setColumnVisible(2, isVisible)
def setTime(self, time):
if not time.isValid() or time.isNull():
......@@ -88,20 +116,26 @@ class AMTimePicker(TimePickerBase):
self.setColumnValue(0, h % 12)
self.setColumnValue(1, str(time.minute()).zfill(2))
self.setColumnValue(2, self.tr('AM') if h < 12 else self.tr('PM'))
self.setColumnValue(2, str(time.second()).zfill(2))
self.setColumnValue(3, self.AM if h < 12 else self.PM)
def _onConfirmed(self, value: list):
super()._onConfirmed(value)
h, m, p = value
h, m = int(h), int(m)
if len(value) == 3:
h, m, p = value
s = 0
else:
h, m, s, p = value
h, m, s = int(h), int(m), int(s)
if p == self.tr('AM'):
if p == self.AM:
h = 0 if h == 12 else h
elif p == self.tr('PM'):
elif p == self.PM:
h = h if h == 12 else h + 12
time = QTime(h, m)
time = QTime(h, m, s)
ot = self.time
self.setTime(time)
......
......@@ -166,6 +166,9 @@ class NavigationPanel(QFrame):
widget.setProperty('routeKey', routeKey)
self.items[routeKey] = widget
if self.displayMode in [NavigationDisplayMode.EXPAND, NavigationDisplayMode.MENU]:
widget.setCompacted(False)
self._addWidgetToLayout(widget, position)
def addSeparator(self, position=NavigationItemPosition.TOP):
......
......@@ -64,6 +64,8 @@ class ScrollButton(QToolButton):
class CycleListWidget(QListWidget):
""" Cycle list widget """
currentItemChanged = pyqtSignal(QListWidgetItem)
def __init__(self, items: Iterable, itemSize: QSize, align=Qt.AlignCenter, parent=None):
"""
Parameters
......@@ -82,6 +84,8 @@ class CycleListWidget(QListWidget):
"""
super().__init__(parent=parent)
self.itemSize = itemSize
self.align = align
self.upButton = ScrollButton(ScrollIcon.UP, self)
self.downButton = ScrollButton(ScrollIcon.DOWN, self)
self.scrollDuration = 250
......@@ -91,14 +95,15 @@ class CycleListWidget(QListWidget):
self.visibleNumber = 9
# repeat adding items to achieve circular scrolling
self._createItems(items, itemSize, align)
self.setItems(items)
self.setVerticalScrollMode(self.ScrollPerPixel)
self.setVerticalScrollBar(self.vScrollBar)
self.vScrollBar.setScrollAnimation(self.scrollDuration)
self.setViewportMargins(0, 0, 0, 0)
self.setFixedSize(itemSize.width()+8, itemSize.height()*self.visibleNumber)
self.setFixedSize(itemSize.width()+8,
itemSize.height()*self.visibleNumber)
# hide scroll bar
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
......@@ -112,13 +117,30 @@ class CycleListWidget(QListWidget):
self.installEventFilter(self)
def _createItems(self, items: list, itemSize: QSize, align=Qt.AlignCenter):
def setItems(self, items: list):
""" set items in the list
Parameters
----------
items: Iterable[Any]
the items to be added
itemSize: QSize
the size of item
align: Qt.AlignmentFlag
the text alignment of item
"""
self.clear()
self._createItems(items)
def _createItems(self, items: list):
N = len(items)
self.isCycle = N > self.visibleNumber
if self.isCycle:
for _ in range(2):
self._addColumnItems(items, itemSize, align)
self._addColumnItems(items)
self._currentIndex = len(items)
super().scrollToItem(
......@@ -126,17 +148,17 @@ class CycleListWidget(QListWidget):
else:
n = self.visibleNumber // 2 # add empty items to enable scrolling
self._addColumnItems(['']*n, itemSize, align, True)
self._addColumnItems(items, itemSize, align)
self._addColumnItems(['']*n, itemSize, align, True)
self._addColumnItems(['']*n, True)
self._addColumnItems(items)
self._addColumnItems(['']*n, True)
self._currentIndex = n
def _addColumnItems(self, items, itemSize, align, disabled=False):
def _addColumnItems(self, items, disabled=False):
for i in items:
item = QListWidgetItem(str(i), self)
item.setSizeHint(itemSize)
item.setTextAlignment(align | Qt.AlignVCenter)
item.setSizeHint(self.itemSize)
item.setTextAlignment(self.align | Qt.AlignVCenter)
if disabled:
item.setFlags(Qt.NoItemFlags)
......@@ -173,6 +195,8 @@ class CycleListWidget(QListWidget):
self.clearSelection()
item.setSelected(False)
self.currentItemChanged.emit(item)
def wheelEvent(self, e):
if e.angleDelta().y() < 0:
self.scrollDown()
......@@ -224,7 +248,8 @@ class CycleListWidget(QListWidget):
def setCurrentIndex(self, index: int):
if not self.isCycle:
n = self.visibleNumber // 2
self._currentIndex = max(n, min(n + len(self.originItems) - 1, index))
self._currentIndex = max(
n, min(n + len(self.originItems) - 1, index))
else:
N = self.count() // 2
m = (self.visibleNumber + 1) // 2
......
......@@ -6,7 +6,7 @@ with open('README.md', encoding='utf-8') as f:
setuptools.setup(
name="PyQt-Fluent-Widgets",
version="0.6.9",
version="0.7.0",
keywords="pyqt fluent widgets",
author="zhiyiYo",
author_email="shokokawaii@outlook.com",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册