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

添加可编辑下拉框 `EditableComboBox`

上级 b43aff7c
# coding:utf-8
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
from qfluentwidgets import ComboBox, setTheme, Theme, setThemeColor
from PyQt5.QtWidgets import QApplication, QWidget
from qfluentwidgets import ComboBox, setTheme, Theme, setThemeColor, EditableComboBox
class Demo(QWidget):
......
......@@ -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"/>
......@@ -39,34 +39,34 @@
<translation>下拉框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="96"/>
<location filename="../../view/basic_input_interface.py" line="112"/>
<source>A group of RadioButton controls in a button group</source>
<translation>單選按鈕</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="107"/>
<location filename="../../view/basic_input_interface.py" line="123"/>
<source>A simple horizontal slider</source>
<translation>水平滑動條</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="116"/>
<location filename="../../view/basic_input_interface.py" line="132"/>
<source>A simple switch button</source>
<translation>開關按鈕</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="126"/>
<location filename="../../view/basic_input_interface.py" line="142"/>
<source>Off</source>
<translation></translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="124"/>
<location filename="../../view/basic_input_interface.py" line="140"/>
<source>On</source>
<translation></translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="23"/>
<source>Standard push button</source>
<translation>按鈕</translation>
<translation>按鈕</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="40"/>
......@@ -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"/>
......@@ -89,19 +89,39 @@
<translation>GItHub 主頁</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="85"/>
<location filename="../../view/basic_input_interface.py" line="101"/>
<source>Star Platinum</source>
<translation>白金之星</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="86"/>
<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="87"/>
<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"/>
<source>Gold Experience</source>
<translation>黃金體驗</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="82"/>
<source>Sticky Fingers</source>
<translation>鋼鏈手指</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="88"/>
<source>Choose your stand</source>
<translation>選擇你的替身</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="90"/>
<source>An editable ComboBox</source>
<translation>可編輯的下拉框</translation>
</message>
</context>
<context>
......@@ -158,7 +178,7 @@
<context>
<name>IconCardView</name>
<message>
<location filename="../../view/icon_interface.py" line="126"/>
<location filename="../../view/icon_interface.py" line="123"/>
<source>Fluent Icons Library</source>
<translation>流暢圖標庫</translation>
</message>
......@@ -166,12 +186,12 @@
<context>
<name>IconInfoPanel</name>
<message>
<location filename="../../view/icon_interface.py" line="84"/>
<location filename="../../view/icon_interface.py" line="81"/>
<source>Icon name</source>
<translation>圖標名字</translation>
</message>
<message>
<location filename="../../view/icon_interface.py" line="86"/>
<location filename="../../view/icon_interface.py" line="83"/>
<source>Enum member</source>
<translation>枚舉成員</translation>
</message>
......@@ -206,7 +226,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"/>
......@@ -242,9 +262,9 @@
<context>
<name>LineEdit</name>
<message>
<location filename="../../view/icon_interface.py" line="24"/>
<location filename="../../view/icon_interface.py" line="21"/>
<source>Search icons</source>
<translation>索圖標</translation>
<translation>索圖標</translation>
</message>
</context>
<context>
......@@ -297,7 +317,7 @@
<message>
<location filename="../../view/main_window.py" line="255"/>
<source>You clicked a customized navigation widget. You can add more custom widgets by calling `NavigationInterface.addWidget()` 😉</source>
<translation>妳點擊了一個自定義的導航項可以通過 `NavigationInterface.addWidget()` 添加更多的自定義導航項</translation>
<translation>你點擊了一個自定義的導航項可以通過 `NavigationInterface.addWidget()` 添加更多的自定義導航項</translation>
</message>
<message>
<location filename="../../view/main_window.py" line="200"/>
......@@ -315,7 +335,7 @@
<message>
<location filename="../../view/material_interface.py" line="29"/>
<source>Acrylic label</source>
<translation>亞克力標</translation>
<translation>亞克力標</translation>
</message>
</context>
<context>
......@@ -333,7 +353,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"/>
......@@ -353,7 +373,7 @@
<message>
<location filename="../../view/menu_interface.py" line="49"/>
<source>Paste</source>
<translation></translation>
<translation></translation>
</message>
<message>
<location filename="../../view/menu_interface.py" line="49"/>
......@@ -449,7 +469,7 @@
<message>
<location filename="../../view/setting_interface.py" line="56"/>
<source>Change the appearance of your application</source>
<translation>調整的應用的外觀</translation>
<translation>調整的應用的外觀</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="56"/>
......@@ -474,12 +494,12 @@
<message>
<location filename="../../view/setting_interface.py" line="67"/>
<source>Change the theme color of you application</source>
<translation>調整的應用的主題色</translation>
<translation>調整的應用的主題色</translation>
</message>
<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"/>
......@@ -494,7 +514,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"/>
......@@ -524,7 +544,7 @@
<message>
<location filename="../../view/setting_interface.py" line="108"/>
<source>The new version will be more stable and have more features</source>
<translation>新版本將更加穩定擁有更多功能建議啟用此選項</translation>
<translation>新版本將更加穩定擁有更多功能建議啟用此選項</translation>
</message>
<message>
<location filename="../../view/setting_interface.py" line="134"/>
......@@ -534,7 +554,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"/>
......@@ -544,7 +564,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"/>
......@@ -597,7 +617,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"/>
......@@ -627,7 +647,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"/>
......@@ -662,7 +682,7 @@
<message>
<location filename="../../view/status_info_interface.py" line="92"/>
<source>When you look long into an abyss, the abyss looks into you.</source>
<translation>妳長時間凝視深淵時深淵也在凝視妳</translation>
<translation>你長時間凝視深淵時深淵也在凝視你</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="104"/>
......@@ -692,7 +712,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"/>
......@@ -702,12 +722,12 @@
<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"/>
<source>With respect, let&apos;s advance towards a new stage of the spin.</source>
<translation>錶達敬意吧錶達出敬意然後邁嚮回旋的另一個全新階段</translation>
<translation>表達敬意吧表達出敬意然後邁向回旋的另一個全新階段</translation>
</message>
<message>
<location filename="../../view/status_info_interface.py" line="179"/>
......@@ -722,7 +742,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"/>
......@@ -767,7 +787,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"/>
......@@ -783,42 +803,42 @@
<context>
<name>TextInterface</name>
<message>
<location filename="../../view/text_interface.py" line="20"/>
<location filename="../../view/text_interface.py" line="21"/>
<source>ko no dio da</source>
<translation></translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="22"/>
<location filename="../../view/text_interface.py" line="23"/>
<source>A LineEdit with a clear button</source>
<translation>帶清空按鈕的 LineEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="36"/>
<location filename="../../view/text_interface.py" line="37"/>
<source>A DoubleSpinBox with a spin button</source>
<translation>帶調節按鈕的 DoubleSpinBox</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="43"/>
<location filename="../../view/text_interface.py" line="44"/>
<source>A DateEdit with a spin button</source>
<translation>帶調節按鈕的 DateEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="50"/>
<location filename="../../view/text_interface.py" line="51"/>
<source>A TimeEdit with a spin button</source>
<translation>帶調節按鈕的 TimeEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="57"/>
<location filename="../../view/text_interface.py" line="58"/>
<source>A DateTimeEdit with a spin button</source>
<translation>帶調節按鈕的 DateTimeEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="29"/>
<location filename="../../view/text_interface.py" line="30"/>
<source>A SpinBox with a spin button</source>
<translation>帶調節按鈕的 SpinBox</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="68"/>
<location filename="../../view/text_interface.py" line="69"/>
<source>A simple TextEdit</source>
<translation>富文本框</translation>
</message>
......
......@@ -39,27 +39,27 @@
<translation>下拉框</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="96"/>
<location filename="../../view/basic_input_interface.py" line="112"/>
<source>A group of RadioButton controls in a button group</source>
<translation>单选按钮</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="107"/>
<location filename="../../view/basic_input_interface.py" line="123"/>
<source>A simple horizontal slider</source>
<translation>水平滑动条</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="116"/>
<location filename="../../view/basic_input_interface.py" line="132"/>
<source>A simple switch button</source>
<translation>开关按钮</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="126"/>
<location filename="../../view/basic_input_interface.py" line="142"/>
<source>Off</source>
<translation></translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="124"/>
<location filename="../../view/basic_input_interface.py" line="140"/>
<source>On</source>
<translation></translation>
</message>
......@@ -89,20 +89,40 @@
<translation>GItHub 主页</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="85"/>
<location filename="../../view/basic_input_interface.py" line="101"/>
<source>Star Platinum</source>
<translation>白金之星</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="86"/>
<location filename="../../view/basic_input_interface.py" line="102"/>
<source>Crazy Diamond</source>
<translation>疯狂钻石</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="87"/>
<location filename="../../view/basic_input_interface.py" line="103"/>
<source>Soft and Wet</source>
<translation>软又湿</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="82"/>
<source>Gold Experience</source>
<translation>黄金体验</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="82"/>
<source>Sticky Fingers</source>
<translation>钢链手指</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="88"/>
<source>Choose your stand</source>
<translation>选择你的替身</translation>
</message>
<message>
<location filename="../../view/basic_input_interface.py" line="90"/>
<source>An editable ComboBox</source>
<translation>可编辑的下拉框</translation>
</message>
</context>
<context>
<name>DialogInterface</name>
......@@ -158,7 +178,7 @@
<context>
<name>IconCardView</name>
<message>
<location filename="../../view/icon_interface.py" line="126"/>
<location filename="../../view/icon_interface.py" line="123"/>
<source>Fluent Icons Library</source>
<translation>流畅图标库</translation>
</message>
......@@ -166,12 +186,12 @@
<context>
<name>IconInfoPanel</name>
<message>
<location filename="../../view/icon_interface.py" line="84"/>
<location filename="../../view/icon_interface.py" line="81"/>
<source>Icon name</source>
<translation>图标名字</translation>
</message>
<message>
<location filename="../../view/icon_interface.py" line="86"/>
<location filename="../../view/icon_interface.py" line="83"/>
<source>Enum member</source>
<translation>枚举成员</translation>
</message>
......@@ -242,7 +262,7 @@
<context>
<name>LineEdit</name>
<message>
<location filename="../../view/icon_interface.py" line="24"/>
<location filename="../../view/icon_interface.py" line="21"/>
<source>Search icons</source>
<translation>搜索图标</translation>
</message>
......@@ -783,42 +803,42 @@
<context>
<name>TextInterface</name>
<message>
<location filename="../../view/text_interface.py" line="20"/>
<location filename="../../view/text_interface.py" line="21"/>
<source>ko no dio da</source>
<translation></translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="22"/>
<location filename="../../view/text_interface.py" line="23"/>
<source>A LineEdit with a clear button</source>
<translation>带清空按钮的 LineEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="36"/>
<location filename="../../view/text_interface.py" line="37"/>
<source>A DoubleSpinBox with a spin button</source>
<translation>带调节按钮的 DoubleSpinBox</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="43"/>
<location filename="../../view/text_interface.py" line="44"/>
<source>A DateEdit with a spin button</source>
<translation>带调节按钮的 DateEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="50"/>
<location filename="../../view/text_interface.py" line="51"/>
<source>A TimeEdit with a spin button</source>
<translation>带调节按钮的 TimeEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="57"/>
<location filename="../../view/text_interface.py" line="58"/>
<source>A DateTimeEdit with a spin button</source>
<translation>带调节按钮的 DateTimeEdit</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="29"/>
<location filename="../../view/text_interface.py" line="30"/>
<source>A SpinBox with a spin button</source>
<translation>带调节按钮的 SpinBox</translation>
</message>
<message>
<location filename="../../view/text_interface.py" line="68"/>
<location filename="../../view/text_interface.py" line="69"/>
<source>A simple TextEdit</source>
<translation>富文本框</translation>
</message>
......
......@@ -2,7 +2,7 @@
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QButtonGroup
from qfluentwidgets import (PushButton, ToolButton, PrimaryPushButton, HyperlinkButton,
ComboBox, RadioButton, CheckBox, Slider, SwitchButton)
ComboBox, RadioButton, CheckBox, Slider, SwitchButton, EditableComboBox)
from .gallery_interface import GalleryInterface
from ..common.translator import Translator
......@@ -77,6 +77,22 @@ class BasicInputInterface(GalleryInterface):
'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/combo_box/demo.py'
)
# editable combo box
comboBox = EditableComboBox()
comboBox.addItems([
self.tr('Star Platinum'),
self.tr('Crazy Diamond'),
self.tr("Gold Experience"),
self.tr('Sticky Fingers'),
])
comboBox.setPlaceholderText(self.tr('Choose your stand'))
comboBox.setMinimumWidth(210)
self.addExampleCard(
self.tr('An editable ComboBox'),
comboBox,
'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/combo_box/demo.py'
)
# radio button
radioWidget = QWidget()
radioLayout = QVBoxLayout(radioWidget)
......
......@@ -17,7 +17,8 @@ class TextInterface(GalleryInterface):
)
# spin box
lineEdit = LineEdit(self.tr('ko no dio da!'), self)
lineEdit = LineEdit(self)
lineEdit.setText(self.tr('ko no dio da!'))
lineEdit.setClearButtonEnabled(True)
self.addExampleCard(
title=self.tr("A LineEdit with a clear button"),
......
......@@ -10,7 +10,7 @@ class Demo(QWidget):
def __init__(self):
super().__init__()
self.lineEdit = LineEdit('', self)
self.lineEdit = LineEdit(self)
self.button = PushButton('按钮', self)
self.textEdit = TextEdit(self)
......@@ -18,7 +18,7 @@ class Demo(QWidget):
self.textEdit.move(110, 200)
self.lineEdit.move(110, 50)
self.button.move(320, 52)
self.lineEdit.resize(200, 33)
self.lineEdit.setClearButtonEnabled(True)
......
......@@ -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.3"
__version__ = "0.6.4"
from .components import *
from .common import *
......
......@@ -2,7 +2,7 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 16 16">
<g>
<path id="path1"
transform="rotate(0,8,8) translate(0,1.19976567076743) scale(0.0374926772114821,0.0374926772114821) "
transform="rotate(0,8,8) translate(-1.8,-1.5) scale(0.0374926772114821,0.0374926772114821) "
fill="#000000"
d="M106.75,170.5L111.1875,170.90625 115,172.125 118.4375,174.15625 121.75,177 256,311.25 390.25,177 393.625,174.156265258789 397.25,172.125 401.125,170.90625 405.25,170.5 409.59375,170.9375 413.625,172.25 417.25,174.281265258789 420.375,176.875 422.96875,180.000015258789 425,183.625 426.312469482422,187.65625 426.75,192 426.359344482422,196.21875 425.187469482422,200.125 423.234344482422,203.71875 420.5,207 271,356.5 267.71875,359.234375 264.125,361.1875 260.21875,362.359375 256,362.75 251.78125,362.359375 247.875,361.1875 244.28125,359.234375 241,356.5 91.5,207 88.765625,203.71875 86.8125,200.125 85.640625,196.21875 85.25,192 85.6875,187.65625 87,183.625 89.03125,180.000015258789 91.625,176.875 94.75,174.281265258789 98.375,172.25 102.40625,170.9375 106.75,170.5z" />
</g>
......
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 16 16">
<g>
<path id="path1" transform="rotate(0,8,8) translate(0,1.19976567076743) scale(0.0374926772114821,0.0374926772114821) " fill="#FFFFFF" d="M106.75,170.5L111.1875,170.90625 115,172.125 118.4375,174.15625 121.75,177 256,311.25 390.25,177 393.625,174.156265258789 397.25,172.125 401.125,170.90625 405.25,170.5 409.59375,170.9375 413.625,172.25 417.25,174.281265258789 420.375,176.875 422.96875,180.000015258789 425,183.625 426.312469482422,187.65625 426.75,192 426.359344482422,196.21875 425.187469482422,200.125 423.234344482422,203.71875 420.5,207 271,356.5 267.71875,359.234375 264.125,361.1875 260.21875,362.359375 256,362.75 251.78125,362.359375 247.875,361.1875 244.28125,359.234375 241,356.5 91.5,207 88.765625,203.71875 86.8125,200.125 85.640625,196.21875 85.25,192 85.6875,187.65625 87,183.625 89.03125,180.000015258789 91.625,176.875 94.75,174.281265258789 98.375,172.25 102.40625,170.9375 106.75,170.5z" />
<path id="path1" transform="rotate(0,8,8) translate(-1.8,-1.5) scale(0.0374926772114821,0.0374926772114821) " fill="#FFFFFF" d="M106.75,170.5L111.1875,170.90625 115,172.125 118.4375,174.15625 121.75,177 256,311.25 390.25,177 393.625,174.156265258789 397.25,172.125 401.125,170.90625 405.25,170.5 409.59375,170.9375 413.625,172.25 417.25,174.281265258789 420.375,176.875 422.96875,180.000015258789 425,183.625 426.312469482422,187.65625 426.75,192 426.359344482422,196.21875 425.187469482422,200.125 423.234344482422,203.71875 420.5,207 271,356.5 267.71875,359.234375 264.125,361.1875 260.21875,362.359375 256,362.75 251.78125,362.359375 247.875,361.1875 244.28125,359.234375 241,356.5 91.5,207 88.765625,203.71875 86.8125,200.125 85.640625,196.21875 85.25,192 85.6875,187.65625 87,183.625 89.03125,180.000015258789 91.625,176.875 94.75,174.281265258789 98.375,172.25 102.40625,170.9375 106.75,170.5z" />
</g>
</svg>
......@@ -30,7 +30,7 @@ ComboBoxMenu>MenuActionListWidget {
ComboBoxMenu>MenuActionListWidget::item {
margin-top: 4px;
padding-left: 0px;
padding-left: 10px;
padding-right: 10px;
border-radius: 5px;
border: none;
......@@ -38,7 +38,7 @@ ComboBoxMenu>MenuActionListWidget::item {
}
ComboBoxMenu>MenuActionListWidget::disbled {
padding-left: 0px;
padding-left: 10px;
padding-right: 10px;
border-radius: 5px;
border: none;
......
......@@ -30,14 +30,14 @@ ComboBoxMenu>MenuActionListWidget {
ComboBoxMenu>MenuActionListWidget::item {
margin-top: 4px;
padding-left: 0px;
padding-left: 10px;
padding-right: 10px;
border-radius: 5px;
border: none;
}
ComboBoxMenu>MenuActionListWidget::item:disbaled {
padding-left: 0px;
padding-left: 10px;
padding-right: 10px;
border-radius: 5px;
border: none;
......
此差异已折叠。
......@@ -113,7 +113,7 @@ def writeSvg(iconPath: str, indexes=None, **attributes):
return dom.toString()
def drawIcon(icon, painter, rect):
def drawIcon(icon, painter, rect, **attributes):
""" draw icon
Parameters
......@@ -126,9 +126,12 @@ def drawIcon(icon, painter, rect):
rect: QRect | QRectF
the rect to render icon
**attribute:
the attribute of svg icon
"""
if isinstance(icon, FluentIconBase):
icon.render(painter, rect)
icon.render(painter, rect, **attributes)
else:
icon = QIcon(icon)
rect = QRectF(rect).toRect()
......@@ -165,7 +168,7 @@ class FluentIconBase:
"""
return QIcon(self.path(theme))
def render(self, painter, rect, theme=Theme.AUTO):
def render(self, painter, rect, theme=Theme.AUTO, indexes=None, **attributes):
""" draw svg icon
Parameters
......@@ -181,8 +184,19 @@ class FluentIconBase:
* `Theme.Light`: black icon
* `Theme.DARK`: white icon
* `Theme.AUTO`: icon color depends on `config.theme`
indexes: List[int]
the svg path to be modified
**attributes:
the attributes of modified path
"""
drawSvgIcon(self.path(theme), painter, rect)
if attributes:
svg = writeSvg(self.path(theme), indexes, **attributes).encode()
else:
svg = self.path(theme)
drawSvgIcon(svg, painter, rect)
class FluentIcon(FluentIconBase, Enum):
......
......@@ -134,7 +134,8 @@ class ColorLineEdit(LineEdit):
valueChanged = pyqtSignal(str)
def __init__(self, value, parent=None):
super().__init__(str(value), parent)
super().__init__(parent)
self.setText(str(value))
self.setFixedSize(136, 33)
self.setClearButtonEnabled(True)
self.setValidator(QIntValidator(0, 255, self))
......
......@@ -46,7 +46,7 @@ class ExpandButton(QAbstractButton):
# draw icon
painter.translate(self.width()//2, self.height()//2)
painter.rotate(self.__angle)
FIF.ARROW_DOWN.render(painter, QRectF(-6, -6, 9.6, 9.6))
FIF.ARROW_DOWN.render(painter, QRectF(-5, -5, 9.6, 9.6))
def enterEvent(self, e):
self.setHover(True)
......
......@@ -13,7 +13,7 @@ from ..widgets.slider import Slider
from ..widgets.icon_widget import IconWidget
from ..widgets.button import HyperlinkButton
from ...common.style_sheet import FluentStyleSheet
from ...common.config import qconfig, isDarkTheme, ConfigItem
from ...common.config import qconfig, isDarkTheme, ConfigItem, OptionsConfigItem
from ...common.icon import FluentIconBase
......@@ -357,7 +357,7 @@ class ColorSettingCard(SettingCard):
class ComboBoxSettingCard(SettingCard):
""" Setting card with a combo box """
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
def __init__(self, configItem: OptionsConfigItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
"""
Parameters
----------
......@@ -385,16 +385,21 @@ class ComboBoxSettingCard(SettingCard):
self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
self.hBoxLayout.addSpacing(16)
self.textToOption = {t: o for t, o in zip(texts, configItem.options)}
self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
self.comboBox.addItems(texts)
for text, option in zip(texts, configItem.options):
self.comboBox.addItem(text, userData=option)
self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
self.comboBox.currentTextChanged.connect(self._onCurrentTextChanged)
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
configItem.valueChanged.connect(self.setValue)
def _onCurrentTextChanged(self, text):
qconfig.set(self.configItem, self.textToOption[text])
def _onCurrentIndexChanged(self, index: int):
qconfig.set(self.configItem, self.comboBox.itemData(index))
def setValue(self, value):
if value not in self.optionToText:
return
self.comboBox.setCurrentText(self.optionToText[value])
qconfig.set(self.configItem, value)
\ No newline at end of file
from .button import PrimaryPushButton, PushButton, RadioButton, HyperlinkButton, ToolButton
from .check_box import CheckBox
from .combo_box import ComboBox
from .combo_box import ComboBox, EditableComboBox
from .line_edit import LineEdit, TextEdit, PlainTextEdit, LineEditButton, SearchLineEdit
from .icon_widget import IconWidget
from .label import PixmapLabel
......
# coding:utf-8
from PyQt5.QtCore import Qt, pyqtSignal, QRect, QRectF, QPoint
from PyQt5.QtGui import QColor, QPainter, QCursor
from PyQt5.QtWidgets import QAction, QPushButton, QWidget
from typing import Dict, Union, List, Iterable
from PyQt5.QtCore import Qt, pyqtSignal, QRect, QRectF, QPoint, QObject, QEvent
from PyQt5.QtGui import QColor, QPainter, QCursor, QIcon
from PyQt5.QtWidgets import QAction, QPushButton, QWidget, QStyledItemDelegate, QStyle
from .menu import RoundMenu
from ...common.config import isDarkTheme
from .line_edit import LineEdit, LineEditButton
from ...common.icon import FluentIconBase, isDarkTheme
from ...common.icon import FluentIcon as FIF
from ...common.style_sheet import FluentStyleSheet, themeColor
class ComboBox(QPushButton):
""" Combo box """
class ComboItem:
""" Combo box item """
def __init__(self, text: str, icon: Union[str, QIcon, FluentIconBase] = None, userData=None):
""" add item
Parameters
----------
text: str
the text of item
icon: str | QIcon | FluentIconBase
the icon of item
userData: Any
user data
"""
self.text = text
self.userData = userData
if icon:
self._icon = QIcon(icon) if isinstance(icon, str) else icon
else:
self._icon = QIcon()
@property
def icon(self):
if isinstance(self._icon, QIcon):
return self._icon
return self._icon.icon()
class ComboBoxBase(QObject):
""" Combo box base """
currentIndexChanged = pyqtSignal(int)
currentTextChanged = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__("", parent)
def __init__(self, parent=None, **kwargs):
super().__init__(parent=parent)
self.isHover = False
self.isPressed = False
self.items = []
self.items = [] # type: List[ComboItem]
self.itemMap = {} # type: Dict[str, ComboItem]
self._currentIndex = -1
self.dropMenu = None
FluentStyleSheet.COMBO_BOX.apply(self)
def addItem(self, text):
FluentStyleSheet.COMBO_BOX.apply(self)
self.installEventFilter(self)
def eventFilter(self, obj, e: QEvent):
if obj is self:
if e.type() == QEvent.MouseButtonPress:
self.isPressed = True
elif e.type() == QEvent.MouseButtonRelease:
self.isPressed = False
elif e.type() == QEvent.Enter:
self.isHover = True
elif e.type() == QEvent.Leave:
self.isHover = False
return super().eventFilter(obj, e)
def addItem(self, text, icon: Union[str, QIcon, FluentIconBase] = None, userData=None):
""" add item
Parameters
----------
text: str
the text of item
icon: str | QIcon | FluentIconBase
"""
self.items.append(text)
if not text or text in self.itemMap:
return
def addItems(self, texts):
item = ComboItem(text, icon, userData)
self.itemMap[text] = item
self.items.append(item)
def addItems(self, texts: Iterable[str]):
""" add items
Parameters
......@@ -42,7 +100,29 @@ class ComboBox(QPushButton):
text: Iterable[str]
the text of item
"""
self.items.extend(texts)
for text in texts:
self.addItem(text)
def removeItem(self, index: int):
""" Removes the item at the given index from the combobox.
This will update the current index if the index is removed.
"""
if not 0 <= index < len(self.items):
return
item = self.items[index]
self.items.pop(index)
self.itemMap.pop(item.text)
if index < self.currentIndex():
self._onItemClicked(self._currentIndex - 1)
elif index == self.currentIndex():
if index > 0:
self._onItemClicked(self._currentIndex - 1)
else:
self.setCurrentIndex(0)
self.currentTextChanged.emit(self.currentText())
self.currentIndexChanged.emit(0)
def currentIndex(self):
return self._currentIndex
......@@ -55,11 +135,11 @@ class ComboBox(QPushButton):
index: int
current index
"""
if not 0 <= index < len(self.items) or self.currentIndex() == index:
if not 0 <= index < len(self.items):
return
self._currentIndex = index
self.setText(self.items[index])
self.setText(self.items[index].text)
def setText(self, text: str):
super().setText(text)
......@@ -69,7 +149,7 @@ class ComboBox(QPushButton):
if not 0 <= self.currentIndex() < len(self.items):
return ''
return self.items[self.currentIndex()]
return self.items[self.currentIndex()].text
def setCurrentText(self, text):
""" set the current text displayed in combo box,
......@@ -80,10 +160,10 @@ class ComboBox(QPushButton):
text: str
text displayed in combo box
"""
if text not in self.items or text == self.currentText():
if text not in self.itemMap or text == self.currentText():
return
self.setCurrentIndex(self.items.index(text))
self.setCurrentIndex(self.items.index(self.itemMap[text]))
def setItemText(self, index, text):
""" set the text of item
......@@ -96,35 +176,41 @@ class ComboBox(QPushButton):
text: str
new text of item
"""
if not 0 <= index < len(self.items):
if text in self.itemMap or not 0 <= index < len(self.items):
return
self.items[index] = text
item = self.itemMap.pop()
item.text = text
self.itemMap[text] = item
if self.currentIndex() == index:
self.setText(text)
def enterEvent(self, e):
self.isHover = True
self.update()
def itemData(self, index: int):
""" Returns the data for the given role in the given index in the combobox """
if not 0 <= index < len(self.items):
return None
def leaveEvent(self, e):
self.isHover = False
self.update()
return self.items[index].userData
def mousePressEvent(self, e):
super().mousePressEvent(e)
self.isPressed = True
self.update()
def setItemData(self, index: int, value):
""" Sets the data role for the item on the given index in the combobox to the specified value """
if 0 <= index < len(self.items):
self.items[index].userData = value
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.isPressed = False
self.update()
def findData(self, data):
""" Returns the index of the item containing the given data, otherwise returns -1 """
for i, item in enumerate(self.items):
if item.userData == data:
return i
if self.dropMenu:
self._closeComboMenu()
else:
self._showComboMenu()
return -1
def findText(self, text: str):
""" Returns the index of the item containing the given text; otherwise returns -1. """
if text not in self.itemMap:
return -1
return self.items.index(self.itemMap[text])
def _closeComboMenu(self):
if not self.dropMenu:
......@@ -145,32 +231,57 @@ class ComboBox(QPushButton):
menu = ComboBoxMenu(self)
for i, item in enumerate(self.items):
menu.addAction(
QAction(item, triggered=lambda c, x=i: self._onItemClicked(x)))
QAction(item.icon, item.text, triggered=lambda c, x=i: self._onItemClicked(x)))
menu.view.setMinimumWidth(self.width())
menu.adjustSize()
if menu.view.width() < self.width():
menu.view.setMinimumWidth(self.width())
menu.adjustSize()
menu.closedSignal.connect(self._onDropMenuClosed)
self.dropMenu = menu
# set the selected item
menu.setDefaultAction(menu.menuActions()[self.currentIndex()])
if self.currentIndex() >= 0 and self.items:
menu.setDefaultAction(menu.menuActions()[self.currentIndex()])
# show menu
x = -menu.width()//2 + menu.layout().contentsMargins().left() + self.width()//2
y = self.height()
menu.exec(self.mapToGlobal(QPoint(x, y)))
def _toggleComboMenu(self):
if self.dropMenu:
self._closeComboMenu()
else:
self._showComboMenu()
def _onItemClicked(self, index):
if index == self.currentIndex():
return
self.setCurrentIndex(index)
self.currentTextChanged.emit(self.currentText())
self.currentIndexChanged.emit(index)
self.currentTextChanged.emit(self.items[index])
class ComboBox(QPushButton, ComboBoxBase):
""" Combo box """
currentIndexChanged = pyqtSignal(int)
currentTextChanged = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent=parent)
def setPlaceholderText(self, text: str):
self.setText(text)
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self._toggleComboMenu()
def paintEvent(self, e):
super().paintEvent(e)
QPushButton.paintEvent(self, e)
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
if self.isHover:
......@@ -178,52 +289,60 @@ class ComboBox(QPushButton):
elif self.isPressed:
painter.setOpacity(0.7)
FIF.ARROW_DOWN.render(painter, QRectF(
self.width()-22, self.height()/2-6, 10, 10))
rect = QRectF(self.width()-22, self.height()/2-5, 10, 10)
if isDarkTheme():
FIF.ARROW_DOWN.render(painter, rect)
else:
FIF.ARROW_DOWN.render(painter, rect, fill="#646464")
class ComboBoxMenuItemWidget(QWidget):
""" Combo box menu item widget """
class EditableComboBox(LineEdit, ComboBoxBase):
""" Editable combo box """
def __init__(self, item, parent=None):
super().__init__(parent)
self.isPressed = False
self.item = item
self.text = item.text()
item.setText('')
currentIndexChanged = pyqtSignal(int)
currentTextChanged = pyqtSignal(str)
def mousePressEvent(self, e):
super().mousePressEvent(e)
self.isPressed = True
self.update()
def __init__(self, parent=None):
super().__init__(parent=parent)
self.dropButton = LineEditButton(FIF.ARROW_DOWN, self)
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.isPressed = False
self.update()
self.setTextMargins(0, 0, 29, 0)
self.dropButton.setFixedSize(30, 25)
self.hBoxLayout.addWidget(self.dropButton, 0, Qt.AlignRight)
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(
QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
self.dropButton.clicked.connect(self._toggleComboMenu)
self.textEdited.connect(self._onTextEdited)
self.returnPressed.connect(lambda: self.addItem(self.text()))
if self.isPressed:
painter.setOpacity(0.7)
def _onTextEdited(self, text: str):
if text not in self.itemMap:
self._currentIndex = -1
else:
self._currentIndex = self.items.index(self.itemMap[text])
# draw text
isLight = not isDarkTheme()
painter.setPen(Qt.black if isLight else Qt.white)
painter.setFont(self.item.font())
painter.drawText(QRect(12, 0, self.width()-10,
self.height()), Qt.AlignVCenter, self.text)
self.currentTextChanged.emit(text)
# draw indicator
if not self.item.isSelected():
def _onDropMenuClosed(self):
self.dropMenu = None
class ComboMenuItemDelegate(QStyledItemDelegate):
""" Combo box drop menu item delegate """
def paint(self, painter: QPainter, option, index):
super().paint(painter, option, index)
if not option.state & QStyle.State_Selected:
return
painter.save()
painter.setRenderHints(
QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
painter.setPen(Qt.NoPen)
painter.setBrush(themeColor())
painter.drawRoundedRect(0, 8, 3, 16, 1.5, 1.5)
painter.drawRoundedRect(0, 11+option.rect.y(), 3, 15, 1.5, 1.5)
painter.restore()
class ComboBoxMenu(RoundMenu):
......@@ -231,13 +350,9 @@ class ComboBoxMenu(RoundMenu):
def __init__(self, parent=None):
super().__init__(title="", parent=parent)
self.view.setViewportMargins(5, 2, 5, 6)
self.view.setItemDelegate(ComboMenuItemDelegate())
FluentStyleSheet.COMBO_BOX.apply(self)
self.setItemHeight(33)
def addAction(self, action):
super().addAction(action)
item = self.view.item(self.view.count()-1)
w = ComboBoxMenuItemWidget(item, self)
w.resize(item.sizeHint())
self.view.setItemWidget(item, w)
......@@ -78,8 +78,7 @@ class InfoIconWidget(QWidget):
if self.icon != InfoBarIcon.INFORMATION:
drawIcon(self.icon, painter, self.rect())
else:
svg = writeSvg(self.icon.path(), [0], fill=themeColor().name())
drawSvgIcon(svg.encode(), painter, self.rect())
drawIcon(self.icon, painter, self.rect(), indexes=[0], fill=themeColor().name())
class InfoBar(QFrame):
......
......@@ -5,7 +5,7 @@ from PyQt5.QtGui import QPainter, QPainterPath, QIcon
from PyQt5.QtWidgets import QHBoxLayout, QLineEdit, QToolButton, QTextEdit, QPlainTextEdit
from ...common.style_sheet import FluentStyleSheet, themeColor
from ...common.icon import writeSvg, isDarkTheme, drawSvgIcon, FluentIconBase
from ...common.icon import isDarkTheme, FluentIconBase, drawIcon
from ...common.icon import FluentIcon as FIF
from ...common.smooth_scroll import SmoothMode, SmoothScroll
from .menu import LineEditMenu, TextEditMenu
......@@ -34,17 +34,16 @@ class LineEditButton(QToolButton):
rect = QRectF((w - iw)/2, (h - ih)/2, iw, ih)
if isDarkTheme():
self._icon.render(painter, rect)
drawIcon(self._icon, painter, rect)
else:
svg = writeSvg(self._icon.path(), fill='#656565')
drawSvgIcon(svg.encode(), painter, rect)
drawIcon(self._icon, painter, rect, fill='#656565')
class LineEdit(QLineEdit):
""" Line edit """
def __init__(self, contents='', parent=None):
super().__init__(contents, parent)
def __init__(self, parent=None):
super().__init__(parent=parent)
self._isClearButtonEnabled = False
FluentStyleSheet.LINE_EDIT.apply(self)
......@@ -117,7 +116,7 @@ class SearchLineEdit(LineEdit):
clearSignal = pyqtSignal()
def __init__(self, parent=None):
super().__init__('', parent)
super().__init__(parent)
self.searchButton = LineEditButton(FIF.SEARCH, self)
self.hBoxLayout.addWidget(self.searchButton, 0, Qt.AlignRight)
......
......@@ -165,7 +165,7 @@ class MenuActionListWidget(QListWidget):
""" set the height of item """
for i in range(self.count()):
item = self.item(i)
item.setSizeHint(item.sizeHint().width(), i)
item.setSizeHint(item.sizeHint().width(), height)
self.adjustSize()
......@@ -206,6 +206,7 @@ class RoundMenu(QWidget):
self.setShadowEffect()
self.hBoxLayout.addWidget(self.view, 1, Qt.AlignCenter)
self.hBoxLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
self.hBoxLayout.setContentsMargins(12, 8, 12, 20)
FluentStyleSheet.MENU.apply(self)
......@@ -236,12 +237,6 @@ class RoundMenu(QWidget):
self.menuItem = item
self.isSubMenu = True if parent else False
def adjustSize(self):
m = self.layout().contentsMargins()
w = self.view.width() + m.left() + m.right()
h = self.view.height() + m.top() + m.bottom()
self.setFixedSize(w, h)
def icon(self):
return self._icon
......
......@@ -6,7 +6,7 @@ with open('README.md', encoding='utf-8') as f:
setuptools.setup(
name="PyQt-Fluent-Widgets",
version="0.6.3",
version="0.6.4",
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.
先完成此消息的编辑!
想要评论请 注册