initial fluent-widgets ui
This commit is contained in:
204
qfluentwidgets/components/material/acrylic_menu.py
Normal file
204
qfluentwidgets/components/material/acrylic_menu.py
Normal file
@ -0,0 +1,204 @@
|
||||
# coding:utf-8
|
||||
from typing import List
|
||||
from PySide6.QtCore import Qt, QRect, QRectF, QSize
|
||||
from PySide6.QtGui import QPainter, QColor, QPainterPath, QAction
|
||||
from PySide6.QtWidgets import QLineEdit, QListWidgetItem, QListWidget
|
||||
|
||||
from ..widgets.menu import (RoundMenu, MenuAnimationType, MenuAnimationManager, MenuActionListWidget,
|
||||
IndicatorMenuItemDelegate, LineEditMenu, MenuIndicatorType, CheckableMenu)
|
||||
from ..widgets.line_edit import CompleterMenu, LineEdit
|
||||
from ..widgets.acrylic_label import AcrylicBrush
|
||||
from ...common.style_sheet import isDarkTheme
|
||||
|
||||
|
||||
class AcrylicMenuActionListWidget(MenuActionListWidget):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.acrylicBrush = AcrylicBrush(self.viewport(), 35)
|
||||
self.setViewportMargins(0, 0, 0, 0)
|
||||
self.setProperty("transparent", True)
|
||||
|
||||
super().addItem(self.createPlaceholderItem(self._topMargin()))
|
||||
super().addItem(self.createPlaceholderItem(self._bottomMargin()))
|
||||
|
||||
def _updateAcrylicColor(self):
|
||||
if isDarkTheme():
|
||||
tintColor = QColor(32, 32, 32, 200)
|
||||
luminosityColor = QColor(0, 0, 0, 0)
|
||||
else:
|
||||
tintColor = QColor(255, 255, 255, 160)
|
||||
luminosityColor = QColor(255, 255, 255, 50)
|
||||
|
||||
self.acrylicBrush.tintColor = tintColor
|
||||
self.acrylicBrush.luminosityColor = luminosityColor
|
||||
|
||||
def _topMargin(self):
|
||||
return 6
|
||||
|
||||
def _bottomMargin(self):
|
||||
return 6
|
||||
|
||||
def setItemHeight(self, height: int):
|
||||
""" set the height of item """
|
||||
if height == self._itemHeight:
|
||||
return
|
||||
|
||||
for i in range(1, self.count() - 1):
|
||||
item = self.item(i)
|
||||
if not self.itemWidget(item):
|
||||
item.setSizeHint(QSize(item.sizeHint().width(), height))
|
||||
|
||||
self._itemHeight = height
|
||||
self.adjustSize()
|
||||
|
||||
def addItem(self, item):
|
||||
return super().insertItem(self.count() - 1, item)
|
||||
|
||||
def createPlaceholderItem(self, height=2):
|
||||
item = QListWidgetItem()
|
||||
item.setSizeHint(QSize(1, height))
|
||||
item.setFlags(Qt.ItemFlag.NoItemFlags)
|
||||
return item
|
||||
|
||||
def clipPath(self):
|
||||
path = QPainterPath()
|
||||
path.addRoundedRect(QRectF(self.rect()).adjusted(0, 0, -2.5, -2.5), 8, 8)
|
||||
return path
|
||||
|
||||
def paintEvent(self, e) -> None:
|
||||
painter = QPainter(self.viewport())
|
||||
painter.setRenderHints(QPainter.Antialiasing |
|
||||
QPainter.SmoothPixmapTransform)
|
||||
|
||||
self.acrylicBrush.clipPath = self.clipPath()
|
||||
self._updateAcrylicColor()
|
||||
self.acrylicBrush.paint()
|
||||
|
||||
super().paintEvent(e)
|
||||
|
||||
|
||||
class AcrylicMenuBase:
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def setUpMenu(self, view):
|
||||
self.hBoxLayout.removeWidget(self.view)
|
||||
self.view.deleteLater()
|
||||
|
||||
self.view = view
|
||||
self.hBoxLayout.addWidget(self.view)
|
||||
|
||||
self.setShadowEffect()
|
||||
|
||||
self.view.itemClicked.connect(self._onItemClicked)
|
||||
self.view.itemEntered.connect(self._onItemEntered)
|
||||
|
||||
def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
|
||||
p = MenuAnimationManager.make(self, aniType)._endPosition(pos)
|
||||
self.view.acrylicBrush.grabImage(QRect(p, self.layout().sizeHint()))
|
||||
super().exec(pos, ani, aniType)
|
||||
|
||||
|
||||
class AcrylicMenu(AcrylicMenuBase, RoundMenu):
|
||||
""" Acrylic menu """
|
||||
|
||||
def __init__(self, title="", parent=None):
|
||||
super().__init__(title, parent)
|
||||
self.setUpMenu(AcrylicMenuActionListWidget(self))
|
||||
|
||||
def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
|
||||
return super().exec(pos, ani, aniType)
|
||||
|
||||
|
||||
class AcrylicCompleterMenuActionListWidget(AcrylicMenuActionListWidget):
|
||||
|
||||
def clipPath(self):
|
||||
path = QPainterPath()
|
||||
path.setFillRule(Qt.FillRule.WindingFill)
|
||||
path.addRoundedRect(QRectF(self.rect()).adjusted(1, 1, -2.5, -2.5), 8, 8)
|
||||
|
||||
if self.property("dropDown"):
|
||||
path.addRect(1, 1, 11, 11)
|
||||
path.addRect(self.width() - 12, 1, 11, 11)
|
||||
else:
|
||||
path.addRect(1, self.height() - 11, 11, 11)
|
||||
path.addRect(self.width() - 12, self.height() - 11, 11, 11)
|
||||
|
||||
return path
|
||||
|
||||
|
||||
class AcrylicCompleterMenu(AcrylicMenuBase, CompleterMenu):
|
||||
""" Acrylic completer menu """
|
||||
|
||||
def __init__(self, lineEdit: LineEdit):
|
||||
super().__init__(lineEdit)
|
||||
self.setUpMenu(AcrylicCompleterMenuActionListWidget(self))
|
||||
|
||||
self.view.setObjectName('completerListWidget')
|
||||
self.view.setItemDelegate(IndicatorMenuItemDelegate())
|
||||
self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
|
||||
self.setItemHeight(33)
|
||||
|
||||
def _onItemClicked(self, item):
|
||||
self._hideMenu(False)
|
||||
self._onCompletionItemSelected(item.text(), self.view.row(item)-1)
|
||||
|
||||
def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
|
||||
return super().exec(pos, ani, aniType)
|
||||
|
||||
def setItems(self, items):
|
||||
""" set completion items """
|
||||
self.view.clear()
|
||||
|
||||
self.items = items
|
||||
|
||||
QListWidget.addItem(self.view, self.view.createPlaceholderItem(self.view._topMargin()))
|
||||
self.view.addItems(items)
|
||||
|
||||
for i in range(1, self.view.count()):
|
||||
item = self.view.item(i)
|
||||
item.setSizeHint(QSize(1, self.itemHeight))
|
||||
|
||||
QListWidget.addItem(self.view, self.view.createPlaceholderItem(self.view._bottomMargin()))
|
||||
|
||||
|
||||
class AcrylicLineEditMenu(AcrylicMenuBase, LineEditMenu):
|
||||
""" Acrylic line edit menu """
|
||||
|
||||
def __init__(self, parent: QLineEdit):
|
||||
super().__init__(parent)
|
||||
self.setUpMenu(AcrylicMenuActionListWidget(self))
|
||||
|
||||
def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
|
||||
return super().exec(pos, ani, aniType)
|
||||
|
||||
|
||||
class AcrylicCheckableMenu(AcrylicMenuBase, CheckableMenu):
|
||||
""" Checkable menu """
|
||||
|
||||
def __init__(self, title="", parent=None, indicatorType=MenuIndicatorType.CHECK):
|
||||
super().__init__(title, parent, indicatorType)
|
||||
self.setUpMenu(AcrylicMenuActionListWidget(self))
|
||||
self.view.setObjectName('checkableListWidget')
|
||||
|
||||
def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
|
||||
return super().exec(pos, ani, aniType)
|
||||
|
||||
|
||||
class AcrylicSystemTrayMenu(AcrylicMenu):
|
||||
""" System tray menu """
|
||||
|
||||
def showEvent(self, e):
|
||||
super().showEvent(e)
|
||||
self.adjustPosition()
|
||||
self.view.acrylicBrush.grabImage(QRect(self.pos(), self.layout().sizeHint()))
|
||||
|
||||
|
||||
class AcrylicCheckableSystemTrayMenu(AcrylicCheckableMenu):
|
||||
""" Checkable system tray menu """
|
||||
|
||||
def showEvent(self, e):
|
||||
super().showEvent(e)
|
||||
self.adjustPosition()
|
||||
Reference in New Issue
Block a user