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

添加下拉列表框

上级 030bdeb7
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
### Acrylic Label ### Acrylic Label
<img width="60%" src="./_static/gallery/acrylic_label.png"/> <img width="60%" src="./_static/gallery/acrylic_label.png"/>
### Combo Box
![](./_static/gallery/combo_box.gif)
### Color Dialog ### Color Dialog
![](./_static/gallery/color_dialog.gif) ![](./_static/gallery/color_dialog.gif)
......
...@@ -61,6 +61,7 @@ PyQt-Fluent-Widgets provides many kinds of setting card: ...@@ -61,6 +61,7 @@ PyQt-Fluent-Widgets provides many kinds of setting card:
| :----------------------: | ------------------------------------------------------------ | | :----------------------: | ------------------------------------------------------------ |
| `HyperlinkCard` | Setting card with a hyper link | | `HyperlinkCard` | Setting card with a hyper link |
| `ColorSettingCard` | Setting card with a color picker | | `ColorSettingCard` | Setting card with a color picker |
| `ComboBoxSettingCard` | Setting card with a combo box |
| `RangeSettingCard` | Setting card with a slider | | `RangeSettingCard` | Setting card with a slider |
| `PushSettingCard` | Setting card with a naive push button | | `PushSettingCard` | Setting card with a naive push button |
| `PrimaryPushSettingCard` | Setting card with a push button highlighted in the background | | `PrimaryPushSettingCard` | Setting card with a push button highlighted in the background |
......
# coding:utf-8
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout
from qfluentwidgets import ComboBox
class Demo(QWidget):
def __init__(self):
super().__init__()
self.comboBox = ComboBox(self)
self.comboBox.addItems(['shoko 🥰', '西宫硝子', 'aiko', '柳井爱子'])
self.comboBox.setCurrentIndex(0)
self.comboBox.currentTextChanged.connect(print)
self.comboBox.move(200, 200)
self.resize(500, 500)
self.setStyleSheet('Demo{background:white}')
if __name__ == '__main__':
# enable dpi scale
QApplication.setHighDpiScaleFactorRoundingPolicy(
Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
app = QApplication(sys.argv)
w = Demo()
w.show()
app.exec_()
\ No newline at end of file
...@@ -26,7 +26,7 @@ class Demo(QWidget): ...@@ -26,7 +26,7 @@ class Demo(QWidget):
menu.addAction(QAction(FIF.icon(FIF.CUT), 'Cut')) menu.addAction(QAction(FIF.icon(FIF.CUT), 'Cut'))
# add sub menu # add sub menu
submenu = RoundMenu(self, "Add to") submenu = RoundMenu("Add to", self)
submenu.setIcon(FIF.icon(FIF.ADD)) submenu.setIcon(FIF.icon(FIF.ADD))
submenu.addActions([ submenu.addActions([
QAction(FIF.icon(FIF.VIDEO), 'Video'), QAction(FIF.icon(FIF.VIDEO), 'Video'),
......
...@@ -3,7 +3,7 @@ from config import cfg, HELP_URL, FEEDBACK_URL, AUTHOR, VERSION, YEAR ...@@ -3,7 +3,7 @@ from config import cfg, HELP_URL, FEEDBACK_URL, AUTHOR, VERSION, YEAR
from qfluentwidgets import (SettingCardGroup, SwitchSettingCard, FolderListSettingCard, from qfluentwidgets import (SettingCardGroup, SwitchSettingCard, FolderListSettingCard,
OptionsSettingCard, RangeSettingCard, PushSettingCard, OptionsSettingCard, RangeSettingCard, PushSettingCard,
ColorSettingCard, HyperlinkCard, PrimaryPushSettingCard, ScrollArea, ColorSettingCard, HyperlinkCard, PrimaryPushSettingCard, ScrollArea,
ExpandLayout, setStyleSheet, ToastToolTip) ComboBoxSettingCard, ExpandLayout, setStyleSheet, ToastToolTip)
from qfluentwidgets import FluentIconFactory as FIF from qfluentwidgets import FluentIconFactory as FIF
from PyQt5.QtCore import Qt, pyqtSignal, QUrl from PyQt5.QtCore import Qt, pyqtSignal, QUrl
from PyQt5.QtGui import QDesktopServices from PyQt5.QtGui import QDesktopServices
...@@ -74,7 +74,7 @@ class SettingInterface(ScrollArea): ...@@ -74,7 +74,7 @@ class SettingInterface(ScrollArea):
], ],
parent=self.personalGroup parent=self.personalGroup
) )
self.languageCard = OptionsSettingCard( self.languageCard = ComboBoxSettingCard(
cfg.language, cfg.language,
FIF.path(FIF.LANGUAGE), FIF.path(FIF.LANGUAGE),
self.tr('Language'), self.tr('Language'),
......
...@@ -10,7 +10,7 @@ online at https://pyqt-fluent-widgets.readthedocs.io. ...@@ -10,7 +10,7 @@ online at https://pyqt-fluent-widgets.readthedocs.io.
:license: MIT, see LICENSE for more details. :license: MIT, see LICENSE for more details.
""" """
__version__ = "0.2.1" __version__ = "0.2.2"
from .components import * from .components import *
from .common import * from .common import *
......
ComboBox {
border: 1px solid rgba(255, 255, 255, 24);
border-radius: 5px;
border-bottom: 1px solid rgba(255, 255, 255, 17);
padding: 5px 31px 5px 11px;
font: 14px 'Segoe UI', 'Microsoft YaHei';
color: white;
background-color: rgb(62, 63, 62);
}
ComboBox:hover {
background-color: rgb(67, 68, 67);
}
ComboBox:pressed {
background-color: rgb(56, 56, 56);
border-bottom: 1px solid rgba(255, 255, 255, 24);
color: rgba(255, 255, 255, 0.63);
}
ComboBoxMenu>MenuActionListWidget {
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 9px;
background-color: rgb(43, 43, 43);
outline: none;
font: 14px 'Segoe UI', 'Microsoft YaHei';
}
ComboBoxMenu>MenuActionListWidget::item {
padding-left: 0px;
padding-right: 10px;
border-radius: 5px;
border: none;
color: white;
}
ComboBoxMenu>MenuActionListWidget::disbled {
padding-left: 0px;
padding-right: 10px;
border-radius: 5px;
border: none;
color: white;
}
ComboBoxMenu>MenuActionListWidget::item:hover {
background-color: rgba(255, 255, 255, 0.08);
}
ComboBoxMenu>MenuActionListWidget::item:selected {
background-color: rgba(255, 255, 255, 0.08);
color: white;
}
ComboBoxMenu>MenuActionListWidget::item:selected:active {
background-color: rgba(255, 255, 255, 0.06);
color: rgba(255, 255, 255, 0.7);
}
\ No newline at end of file
ComboBox {
border: 1px solid rgb(238, 239, 238);
border-radius: 5px;
border-bottom: 1px solid rgb(212, 213, 212);
padding: 5px 31px 5px 11px;
font: 14px 'Segoe UI', 'Microsoft YaHei';
color: black;
background-color: rgb(254, 254, 254);
}
ComboBox:hover {
background-color: rgb(251, 251, 251);
}
ComboBox:pressed {
background-color: rgb(252, 252, 252);
border-bottom: 1px solid rgb(238, 239, 238);
color: rgba(0, 0, 0, 0.63);
}
ComboBoxMenu>MenuActionListWidget {
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 9px;
background-color: rgb(249, 249, 249);
outline: none;
font: 14px 'Segoe UI', 'Microsoft YaHei';
}
ComboBoxMenu>MenuActionListWidget::item {
padding-left: 0px;
padding-right: 10px;
border-radius: 5px;
border: none;
}
ComboBoxMenu>MenuActionListWidget::item:disbaled {
padding-left: 0px;
padding-right: 10px;
border-radius: 5px;
border: none;
color: black;
}
ComboBoxMenu>MenuActionListWidget::item:hover {
background-color: rgba(0, 0, 0, 9);
}
ComboBoxMenu>MenuActionListWidget::item:selected {
background-color: rgba(0, 0, 0, 7);
color: black;
}
ComboBoxMenu>MenuActionListWidget::item:selected:active {
background-color: rgba(0, 0, 0, 0.06);
color: rgba(0, 0, 0, 0.7);
}
\ No newline at end of file
此差异已折叠。
...@@ -98,6 +98,7 @@ ...@@ -98,6 +98,7 @@
<file>qss/dark/tool_tip.qss</file> <file>qss/dark/tool_tip.qss</file>
<file>qss/dark/folder_list_dialog.qss</file> <file>qss/dark/folder_list_dialog.qss</file>
<file>qss/dark/setting_interface.qss</file> <file>qss/dark/setting_interface.qss</file>
<file>qss/dark/combo_box.qss</file>
<file>qss/light/color_dialog.qss</file> <file>qss/light/color_dialog.qss</file>
<file>qss/light/dialog.qss</file> <file>qss/light/dialog.qss</file>
...@@ -111,5 +112,6 @@ ...@@ -111,5 +112,6 @@
<file>qss/light/tool_tip.qss</file> <file>qss/light/tool_tip.qss</file>
<file>qss/light/folder_list_dialog.qss</file> <file>qss/light/folder_list_dialog.qss</file>
<file>qss/light/setting_interface.qss</file> <file>qss/light/setting_interface.qss</file>
<file>qss/light/combo_box.qss</file>
</qresource> </qresource>
</RCC> </RCC>
\ No newline at end of file
from .setting_card import (SettingCard, SwitchSettingCard, RangeSettingCard, from .setting_card import (SettingCard, SwitchSettingCard, RangeSettingCard,
PushSettingCard, ColorSettingCard, HyperlinkCard, PushSettingCard, ColorSettingCard, HyperlinkCard,
PrimaryPushSettingCard, ColorPickerButton) PrimaryPushSettingCard, ColorPickerButton, ComboBoxSettingCard)
from .expand_setting_card import ExpandSettingCard from .expand_setting_card import ExpandSettingCard
from .folder_list_setting_card import FolderListSettingCard from .folder_list_setting_card import FolderListSettingCard
from .options_setting_card import OptionsSettingCard from .options_setting_card import OptionsSettingCard
......
...@@ -12,8 +12,7 @@ class OptionsSettingCard(ExpandSettingCard): ...@@ -12,8 +12,7 @@ class OptionsSettingCard(ExpandSettingCard):
optionChanged = pyqtSignal(OptionsConfigItem) optionChanged = pyqtSignal(OptionsConfigItem)
def __init__(self, configItem: OptionsConfigItem, iconPath: str, title: str, content: str = None, def __init__(self, configItem, iconPath, title, content=None, texts=None, parent=None):
texts: List[str] = None, parent=None):
""" """
Parameters Parameters
---------- ----------
......
# coding:utf-8 # coding:utf-8
from PyQt5.QtCore import QUrl, Qt, pyqtSignal from PyQt5.QtCore import QUrl, Qt, pyqtSignal
from PyQt5.QtGui import QColor, QDesktopServices from PyQt5.QtGui import QColor, QDesktopServices
from PyQt5.QtWidgets import QFrame, QHBoxLayout, QLabel, QToolButton, QVBoxLayout, QPushButton from PyQt5.QtWidgets import (QFrame, QHBoxLayout, QLabel, QToolButton,
QVBoxLayout, QPushButton)
from PyQt5.QtSvg import QSvgWidget from PyQt5.QtSvg import QSvgWidget
from ..dialog_box.color_dialog import ColorDialog from ..dialog_box.color_dialog import ColorDialog
from ..widgets.combo_box import ComboBox
from ..widgets.switch_button import SwitchButton, IndicatorPosition from ..widgets.switch_button import SwitchButton, IndicatorPosition
from ..widgets.slider import Slider from ..widgets.slider import Slider
from ...common.style_sheet import setStyleSheet, getStyleSheet from ...common.style_sheet import setStyleSheet, getStyleSheet
from ...common.config import ConfigItem, qconfig, RangeConfigItem from ...common.config import qconfig, OptionsConfigItem
from ...common.icon import getIconColor
class SettingCard(QFrame): class SettingCard(QFrame):
""" Setting card """ """ Setting card """
def __init__(self, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, iconPath, title, content=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -80,7 +81,7 @@ class SwitchSettingCard(SettingCard): ...@@ -80,7 +81,7 @@ class SwitchSettingCard(SettingCard):
checkedChanged = pyqtSignal(bool) checkedChanged = pyqtSignal(bool)
def __init__(self, iconPath: str, title: str, content: str = None, configItem: ConfigItem = None, parent=None): def __init__(self, iconPath, title, content=None, configItem=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -138,7 +139,7 @@ class RangeSettingCard(SettingCard): ...@@ -138,7 +139,7 @@ class RangeSettingCard(SettingCard):
valueChanged = pyqtSignal(int) valueChanged = pyqtSignal(int)
def __init__(self, configItem: RangeConfigItem, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, configItem, iconPath, title, content=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -189,7 +190,7 @@ class PushSettingCard(SettingCard): ...@@ -189,7 +190,7 @@ class PushSettingCard(SettingCard):
clicked = pyqtSignal() clicked = pyqtSignal()
def __init__(self, text, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, text, iconPath, title, content=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -218,7 +219,7 @@ class PushSettingCard(SettingCard): ...@@ -218,7 +219,7 @@ class PushSettingCard(SettingCard):
class PrimaryPushSettingCard(PushSettingCard): class PrimaryPushSettingCard(PushSettingCard):
""" Push setting card with primary color """ """ Push setting card with primary color """
def __init__(self, text: str, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, text, iconPath, title, content=None, parent=None):
super().__init__(text, iconPath, title, content, parent) super().__init__(text, iconPath, title, content, parent)
self.button.setObjectName('primaryButton') self.button.setObjectName('primaryButton')
...@@ -226,7 +227,7 @@ class PrimaryPushSettingCard(PushSettingCard): ...@@ -226,7 +227,7 @@ class PrimaryPushSettingCard(PushSettingCard):
class HyperlinkCard(SettingCard): class HyperlinkCard(SettingCard):
""" Hyperlink card """ """ Hyperlink card """
def __init__(self, url: str, text: str, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, url, text, iconPath, title, content=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -306,7 +307,7 @@ class ColorSettingCard(SettingCard): ...@@ -306,7 +307,7 @@ class ColorSettingCard(SettingCard):
colorChanged = pyqtSignal(QColor) colorChanged = pyqtSignal(QColor)
def __init__(self, configItem: ConfigItem, iconPath: str, title: str, content: str = None, parent=None): def __init__(self, configItem, iconPath, title, content=None, parent=None):
""" """
Parameters Parameters
---------- ----------
...@@ -338,40 +339,42 @@ class ColorSettingCard(SettingCard): ...@@ -338,40 +339,42 @@ class ColorSettingCard(SettingCard):
self.colorChanged.emit(color) self.colorChanged.emit(color)
class SettingIconFactory: class ComboBoxSettingCard(SettingCard):
""" Setting icon factory """ """ Setting card with a combo box """
WEB = "Web" def __init__(self, configItem, iconPath, title, content=None, texts=None, parent=None):
LINK = "Link" """
HELP = "Help" Parameters
FONT = "Font" ----------
INFO = "Info" configItem: OptionsConfigItem
ZOOM = "Zoom" configuration item operated by the card
CLOSE = "Close"
MOVIE = "Movie" iconPath: str
BRUSH = "Brush" the path of icon
MUSIC = "Music"
VIDEO = "Video" title: str
EMBED = "Embed" the title of card
FOLDER = "Folder"
SEARCH = "Search" content: str
UPDATE = "Update" the content of card
PALETTE = "Palette"
FEEDBACK = "Feedback" texts: List[str]
MINIMIZE = "Minimize" the text of items
LANGUAGE = "Language"
DOWNLOAD = "Download" parent: QWidget
QUESTION = "Question" parent widget
ALIGNMENT = "Alignment" """
PENCIL_INK = "PencilInk" super().__init__(iconPath, title, content, parent)
FOLDER_ADD = "FolderAdd" self.configItem = configItem
ARROW_DOWN = "ChevronDown" self.comboBox = ComboBox(self)
TRANSPARENT = "Transparent" self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
MUSIC_FOLDER = "MusicFolder" self.hBoxLayout.addSpacing(16)
BACKGROUND_FILL = "BackgroundColor"
FLUORESCENT_PEN = "FluorescentPen" self.textToOption = {t: o for t, o in zip(texts, configItem.options)}
self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
@staticmethod self.comboBox.addItems(texts)
def create(iconType: str): self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
""" create icon """ self.comboBox.currentTextChanged.connect(self._onCurrentTextChanged)
return f':/qfluentwidgets/images/setting_card/{iconType}_{getIconColor()}.svg'
def _onCurrentTextChanged(self, text):
qconfig.set(self.configItem, self.textToOption[text])
\ No newline at end of file
from .combo_box import ComboBox
from .menu import DWMMenu, LineEditMenu, RoundMenu from .menu import DWMMenu, LineEditMenu, RoundMenu
from .slider import Slider, HollowHandleStyle from .slider import Slider, HollowHandleStyle
from .stacked_widget import PopUpAniStackedWidget, OpacityAniStackedWidget from .stacked_widget import PopUpAniStackedWidget, OpacityAniStackedWidget
......
# 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 .menu import RoundMenu
from ...common.config import qconfig
from ...common.icon import FluentIconFactory as FIF
from ...common.style_sheet import setStyleSheet
class ComboBox(QPushButton):
""" Combo box """
currentIndexChanged = pyqtSignal(int)
currentTextChanged = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__("", parent)
self.isHover = False
self.isPressed = False
self.items = []
self._currentIndex = -1
setStyleSheet(self, 'combo_box')
def addItem(self, text):
""" add item
Parameters
----------
text: str
the text of item
"""
self.items.append(text)
def addItems(self, texts):
""" add items
Parameters
----------
text: Iterable[str]
the text of item
"""
self.items.extend(texts)
def currentIndex(self):
return self._currentIndex
def setCurrentIndex(self, index):
""" set current index
Parameters
----------
index: int
current index
"""
if not 0 <= index < len(self.items) or self.currentIndex() == index:
return
self._currentIndex = index
self.setText(self.items[index])
def setText(self, text: str):
super().setText(text)
self.adjustSize()
def currentText(self):
if not 0 <= self.currentIndex() < len(self.items):
return ''
return self.items[self.currentIndex()]
def setCurrentText(self, text):
""" set the current text displayed in combo box,
text should be in the item list
Parameters
----------
text: str
text displayed in combo box
"""
if text not in self.items or text == self.currentText():
return
self.setCurrentIndex(self.items.index(text))
def setItemText(self, index, text):
""" set the text of item
Parameters
----------
index: int
the index of item
text: str
new text of item
"""
if not 0 <= index < len(self.items):
return
self.items[index] = text
if self.currentIndex() == index:
self.setText(text)
def enterEvent(self, e):
self.isHover = True
self.update()
def leaveEvent(self, e):
self.isHover = False
self.update()
def mousePressEvent(self, e):
super().mousePressEvent(e)
self.isPressed = True
self.update()
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.isPressed = False
self.update()
self._showComboMenu()
def _showComboMenu(self):
menu = ComboBoxMenu(self)
for i, item in enumerate(self.items):
menu.addAction(
QAction(item, triggered=lambda c, x=i: self._onItemClicked(x)))
# set the selected item
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 _onItemClicked(self, index):
if index == self.currentIndex():
return
self.setCurrentIndex(index)
self.currentIndexChanged.emit(index)
self.currentTextChanged.emit(self.items[index])
def paintEvent(self, e):
super().paintEvent(e)
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
if self.isHover:
painter.setOpacity(0.8)
elif self.isPressed:
painter.setOpacity(0.7)
FIF.render(FIF.ARROW_DOWN, painter, QRectF(
self.width()-22, self.height()/2-6, 10, 10))
class ComboBoxMenuItemWidget(QWidget):
""" Combo box menu item widget """
def __init__(self, item, parent=None):
super().__init__(parent)
self.isPressed = False
self.item = item
self.text = item.text()
item.setText('')
def mousePressEvent(self, e):
super().mousePressEvent(e)
self.isPressed = True
self.update()
def mouseReleaseEvent(self, e):
super().mouseReleaseEvent(e)
self.isPressed = False
self.update()
def paintEvent(self, e):
painter = QPainter(self)
painter.setRenderHints(
QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
if self.isPressed:
painter.setOpacity(0.7)
# draw text
isLight = qconfig.theme == 'light'
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)
# draw indicator
if not self.item.isSelected():
return
painter.setPen(Qt.NoPen)
if isLight:
painter.setBrush(QColor(0, 159, 170))
else:
painter.setBrush(QColor(41, 247, 255))
painter.drawRoundedRect(0, 8, 3, 16, 1.5, 1.5)
class ComboBoxMenu(RoundMenu):
""" Combo box menu """
def __init__(self, parent=None):
super().__init__(title="", parent=parent)
setStyleSheet(self, 'combo_box')
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)
...@@ -153,8 +153,7 @@ class MenuSeparator(QWidget): ...@@ -153,8 +153,7 @@ class MenuSeparator(QWidget):
class SubMenuItemWidget(QWidget): class SubMenuItemWidget(QWidget):
""" Sub menu item """ """ Sub menu item """
showMenuSig = pyqtSignal() showMenuSig = pyqtSignal(QListWidgetItem)
hideMenuSig = pyqtSignal()
def __init__(self, menu, item, parent=None): def __init__(self, menu, item, parent=None):
""" """
...@@ -175,17 +174,11 @@ class SubMenuItemWidget(QWidget): ...@@ -175,17 +174,11 @@ class SubMenuItemWidget(QWidget):
def enterEvent(self, e): def enterEvent(self, e):
super().enterEvent(e) super().enterEvent(e)
self.showMenuSig.emit() self.showMenuSig.emit(self.item)
def paintEvent(self, e): def paintEvent(self, e):
painter = QPainter(self) painter = QPainter(self)
painter.setRenderHints( painter.setRenderHints(QPainter.Antialiasing)
QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing)
# draw icon and text
option = QStyleOptionViewItem()
option.initFrom(self.parent())
self.style().drawPrimitive(QStyle.PE_PanelItemViewRow, option, painter)
# draw right arrow # draw right arrow
FIF.render(FIF.CHEVRON_RIGHT, painter, QRectF( FIF.render(FIF.CHEVRON_RIGHT, painter, QRectF(
...@@ -202,6 +195,7 @@ class MenuActionListWidget(QListWidget): ...@@ -202,6 +195,7 @@ class MenuActionListWidget(QListWidget):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setTextElideMode(Qt.ElideNone) self.setTextElideMode(Qt.ElideNone)
self.setDragEnabled(False) self.setDragEnabled(False)
self.setMouseTracking(True)
self.setVerticalScrollMode(self.ScrollPerPixel) self.setVerticalScrollMode(self.ScrollPerPixel)
self.setIconSize(QSize(14, 14)) self.setIconSize(QSize(14, 14))
self.smoothScroll = SmoothScroll(self) self.smoothScroll = SmoothScroll(self)
...@@ -235,15 +229,18 @@ class MenuActionListWidget(QListWidget): ...@@ -235,15 +229,18 @@ class MenuActionListWidget(QListWidget):
size.setHeight(size.height() + s.height()) size.setHeight(size.height() + s.height())
# adjust the height of viewport # adjust the height of viewport
h = QApplication.screenAt(QCursor.pos()).availableSize().height()-100 ss = QApplication.screenAt(QCursor.pos()).availableSize()
w, h = ss.width() - 100, ss.height() - 100
vsize = QSize(size) vsize = QSize(size)
vsize.setHeight(min(h-12, vsize.height())) vsize.setHeight(min(h-12, vsize.height()))
vsize.setWidth(min(w-12, vsize.width()))
self.viewport().adjustSize() self.viewport().adjustSize()
# adjust the height of list widget # adjust the height of list widget
size.setHeight(min(h, size.height()+3))
m = self.viewportMargins() m = self.viewportMargins()
size += QSize(m.left()+m.right()+2, m.top()+m.bottom()) size += QSize(m.left()+m.right()+2, m.top()+m.bottom())
size.setHeight(min(h, size.height()+3))
size.setWidth(min(w, size.width()))
self.setFixedSize(size) self.setFixedSize(size)
def setItemHeight(self, height): def setItemHeight(self, height):
...@@ -258,7 +255,7 @@ class MenuActionListWidget(QListWidget): ...@@ -258,7 +255,7 @@ class MenuActionListWidget(QListWidget):
class RoundMenu(QWidget): class RoundMenu(QWidget):
""" Round corner menu """ """ Round corner menu """
def __init__(self, parent, title=""): def __init__(self, title="", parent=None):
super().__init__(parent=parent) super().__init__(parent=parent)
self._title = title self._title = title
self._icon = QIcon() self._icon = QIcon()
...@@ -279,11 +276,13 @@ class RoundMenu(QWidget): ...@@ -279,11 +276,13 @@ class RoundMenu(QWidget):
self.setMouseTracking(True) self.setMouseTracking(True)
self.setShadowEffect() self.setShadowEffect()
self.hBoxLayout.addWidget(self.view) self.hBoxLayout.addWidget(self.view, 1, Qt.AlignCenter)
self.hBoxLayout.setContentsMargins(12, 8, 12, 20) self.hBoxLayout.setContentsMargins(12, 8, 12, 20)
setStyleSheet(self, 'menu') setStyleSheet(self, 'menu')
self.view.itemClicked.connect(self._onItemClicked) self.view.itemClicked.connect(self._onItemClicked)
self.view.itemEntered.connect(self._onItemEntered)
self.ani.valueChanged.connect(self._onSlideValueChanged) self.ani.valueChanged.connect(self._onSlideValueChanged)
def setItemHeight(self, height): def setItemHeight(self, height):
...@@ -300,6 +299,7 @@ class RoundMenu(QWidget): ...@@ -300,6 +299,7 @@ class RoundMenu(QWidget):
self.shadowEffect.setBlurRadius(blurRadius) self.shadowEffect.setBlurRadius(blurRadius)
self.shadowEffect.setOffset(*offset) self.shadowEffect.setOffset(*offset)
self.shadowEffect.setColor(color) self.shadowEffect.setColor(color)
self.view.setGraphicsEffect(None)
self.view.setGraphicsEffect(self.shadowEffect) self.view.setGraphicsEffect(self.shadowEffect)
def _setParentMenu(self, parent, item): def _setParentMenu(self, parent, item):
...@@ -307,6 +307,12 @@ class RoundMenu(QWidget): ...@@ -307,6 +307,12 @@ class RoundMenu(QWidget):
self.menuItem = item self.menuItem = item
self.isSubMenu = True if parent else False 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): def icon(self):
return self._icon return self._icon
...@@ -332,6 +338,7 @@ class RoundMenu(QWidget): ...@@ -332,6 +338,7 @@ class RoundMenu(QWidget):
""" """
item = self._createMenuActionItem(action) item = self._createMenuActionItem(action)
self.view.addItem(item) self.view.addItem(item)
self.adjustSize()
def _createMenuActionItem(self, action, before=None): def _createMenuActionItem(self, action, before=None):
""" create menu action item """ """ create menu action item """
...@@ -379,6 +386,7 @@ class RoundMenu(QWidget): ...@@ -379,6 +386,7 @@ class RoundMenu(QWidget):
index = self.view.row(beforeItem) index = self.view.row(beforeItem)
item = self._createMenuActionItem(action, before) item = self._createMenuActionItem(action, before)
self.view.insertItem(index, item) self.view.insertItem(index, item)
self.adjustSize()
def addActions(self, actions): def addActions(self, actions):
""" add actions to menu """ add actions to menu
...@@ -455,23 +463,17 @@ class RoundMenu(QWidget): ...@@ -455,23 +463,17 @@ class RoundMenu(QWidget):
item.setData(Qt.UserRole, menu) item.setData(Qt.UserRole, menu)
w = SubMenuItemWidget(menu, item, self) w = SubMenuItemWidget(menu, item, self)
w.showMenuSig.connect(self._showSubMenu) w.showMenuSig.connect(self._showSubMenu)
w.hideMenuSig.connect(self._hideSubMenu) w.resize(item.sizeHint())
self.view.addItem(item) self.view.addItem(item)
self.view.setItemWidget(item, w) self.view.setItemWidget(item, w)
self.adjustSize()
def _showSubMenu(self): def _showSubMenu(self, item):
""" show sub menu """ """ show sub menu """
w = self.sender() w = self.view.itemWidget(item)
pos = w.mapToGlobal(QPoint()) pos = w.mapToGlobal(QPoint(w.width()+5, -5))
pos += QPoint(w.width()-6, 0)
w.menu.exec(pos) w.menu.exec(pos)
def _hideSubMenu(self):
""" hide sub menu """
w = self.sender()
w.item.setSelected(False)
w.menu.hide()
def addSeparator(self): def addSeparator(self):
""" add seperator to menu """ """ add seperator to menu """
m = self.view.viewportMargins() m = self.view.viewportMargins()
...@@ -487,6 +489,7 @@ class RoundMenu(QWidget): ...@@ -487,6 +489,7 @@ class RoundMenu(QWidget):
item.setSizeHint(QSize(w, separator.height())) item.setSizeHint(QSize(w, separator.height()))
self.view.addItem(item) self.view.addItem(item)
self.view.setItemWidget(item, separator) self.view.setItemWidget(item, separator)
self.adjustSize()
def _onItemClicked(self, item): def _onItemClicked(self, item):
action = item.data(Qt.UserRole) action = item.data(Qt.UserRole)
...@@ -506,6 +509,12 @@ class RoundMenu(QWidget): ...@@ -506,6 +509,12 @@ class RoundMenu(QWidget):
menu.deleteLater() menu.deleteLater()
def _onItemEntered(self, item):
if not isinstance(item.data(Qt.UserRole), RoundMenu):
return
self._showSubMenu(item)
def _hideMenu(self): def _hideMenu(self):
self.view.clearSelection() self.view.clearSelection()
if self.isSubMenu: if self.isSubMenu:
...@@ -527,8 +536,11 @@ class RoundMenu(QWidget): ...@@ -527,8 +536,11 @@ class RoundMenu(QWidget):
# hide submenu when mouse moves out of submenu item # hide submenu when mouse moves out of submenu item
pos = e.globalPos() pos = e.globalPos()
view = self.parentMenu.view view = self.parentMenu.view
w = view.itemWidget(self.menuItem)
rect = w.geometry().translated(w.mapToGlobal(QPoint())-w.pos()) # get the rect of menu item
margin = view.viewportMargins()
rect = view.visualItemRect(self.menuItem).translated(view.mapToGlobal(QPoint()))
rect= rect.translated(margin.left(), margin.top()+2)
mr = self.geometry() mr = self.geometry()
mr.setHeight(self.itemHeight + 10) mr.setHeight(self.itemHeight + 10)
if self.parentMenu.geometry().contains(pos) and not rect.contains(pos) and \ if self.parentMenu.geometry().contains(pos) and not rect.contains(pos) and \
...@@ -561,12 +573,13 @@ class RoundMenu(QWidget): ...@@ -561,12 +573,13 @@ class RoundMenu(QWidget):
ani: bool ani: bool
Whether to show pop-up animation Whether to show pop-up animation
""" """
if self.isVisible():
return
desktop = QApplication.desktop().availableGeometry() desktop = QApplication.desktop().availableGeometry()
m = self.layout().contentsMargins() w, h = self.width() + 20, self.height() + 20
w = self.view.width() + m.left() + m.right() + 20 pos.setX(max(10, min(pos.x() - self.layout().contentsMargins().left(), desktop.width() - w)))
h = self.view.height() + m.top() + m.bottom() + 20 pos.setY(max(10, min(pos.y() - 4, desktop.height() - h)))
pos.setX(min(pos.x() - 30, desktop.width() - w))
pos.setY(min(pos.y() - 10, desktop.height() - h))
if ani: if ani:
self.ani.setStartValue(pos-QPoint(0, h/2)) self.ani.setStartValue(pos-QPoint(0, h/2))
......
...@@ -6,7 +6,7 @@ with open('README.md', encoding='utf-8') as f: ...@@ -6,7 +6,7 @@ with open('README.md', encoding='utf-8') as f:
setuptools.setup( setuptools.setup(
name="PyQt-Fluent-Widgets", name="PyQt-Fluent-Widgets",
version="0.2.1", version="0.2.2",
keywords="pyqt fluent widgets", keywords="pyqt fluent widgets",
author="zhiyiYo", author="zhiyiYo",
author_email="shokokawaii@outlook.com", author_email="shokokawaii@outlook.com",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册