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

添加自定义菜单组件的功能

上级 bcf509b5
# coding:utf-8 # coding:utf-8
from PyQt5.QtCore import QPoint, Qt, QStandardPaths from PyQt5.QtCore import QPoint, Qt, QStandardPaths
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QAction, QWidget, QLabel, QVBoxLayout, QFileDialog, QActionGroup from PyQt5.QtWidgets import QAction, QWidget, QLabel, QVBoxLayout, QFileDialog, QActionGroup
from qfluentwidgets import (RoundMenu, PushButton, Action, CommandBar, Action, TransparentDropDownPushButton, from qfluentwidgets import (RoundMenu, PushButton, Action, CommandBar, Action, TransparentDropDownPushButton,
setFont, CommandBarView, Flyout, ImageLabel, FlyoutAnimationType, CheckableMenu, setFont, CommandBarView, Flyout, ImageLabel, FlyoutAnimationType, CheckableMenu,
MenuIndicatorType) MenuIndicatorType, AvatarWidget, isDarkTheme, BodyLabel, CaptionLabel, HyperlinkButton)
from qfluentwidgets import FluentIcon as FIF from qfluentwidgets import FluentIcon as FIF
from .gallery_interface import GalleryInterface from .gallery_interface import GalleryInterface
...@@ -53,6 +54,18 @@ class MenuInterface(GalleryInterface): ...@@ -53,6 +54,18 @@ class MenuInterface(GalleryInterface):
'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/menu/demo.py' 'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/menu/demo.py'
) )
# custom widget menu
self.button3 = PushButton(self.tr('Show menu'))
self.button3.clicked.connect(lambda: self.createCustomWidgetMenu(
self.button3.mapToGlobal(QPoint(self.button3.width()+5, -100))))
self.addExampleCard(
self.tr('Rounded corners menu with custom widget'),
self.button3,
'https://github.com/zhiyiYo/PyQt-Fluent-Widgets/blob/master/examples/widget_menu/demo.py'
)
# checkable menu # checkable menu
self.button2 = PushButton(self.tr('Show menu')) self.button2 = PushButton(self.tr('Show menu'))
self.button2.clicked.connect(lambda: self.createCheckableMenu( self.button2.clicked.connect(lambda: self.createCheckableMenu(
...@@ -133,6 +146,23 @@ class MenuInterface(GalleryInterface): ...@@ -133,6 +146,23 @@ class MenuInterface(GalleryInterface):
menu.exec(pos, ani=True) menu.exec(pos, ani=True)
def createCustomWidgetMenu(self, pos):
menu = RoundMenu(parent=self)
# add custom widget
card = ProfileCard(':/gallery/images/shoko.png', self.tr('Shoko'), 'shokokawaii@outlook.com', menu)
menu.addWidget(card, selectable=False)
menu.addSeparator()
menu.addActions([
Action(FIF.PEOPLE, self.tr('Manage account profile')),
Action(FIF.SHOPPING_CART, self.tr('Payment method')),
Action(FIF.CODE, self.tr('Redemption code and gift card')),
])
menu.addSeparator()
menu.addAction(Action(FIF.SETTING, self.tr('Settings')))
menu.exec(pos)
def createCheckableMenu(self, pos=None): def createCheckableMenu(self, pos=None):
menu = CheckableMenu(parent=self, indicatorType=MenuIndicatorType.RADIO) menu = CheckableMenu(parent=self, indicatorType=MenuIndicatorType.RADIO)
...@@ -203,4 +233,30 @@ class MenuInterface(GalleryInterface): ...@@ -203,4 +233,30 @@ class MenuInterface(GalleryInterface):
if not ok: if not ok:
return return
self.imageLabel.image.save(path) self.imageLabel.image.save(path)
\ No newline at end of file
class ProfileCard(QWidget):
""" Profile card """
def __init__(self, avatarPath: str, name: str, email: str, parent=None):
super().__init__(parent=parent)
self.avatar = AvatarWidget(avatarPath, self)
self.nameLabel = BodyLabel(name, self)
self.emailLabel = CaptionLabel(email, self)
self.logoutButton = HyperlinkButton(
'https://github.com/zhiyiYo/QMaterialWidgets', '注销', self)
color = QColor(206, 206, 206) if isDarkTheme() else QColor(96, 96, 96)
self.emailLabel.setStyleSheet('QLabel{color: '+color.name()+'}')
color = QColor(255, 255, 255) if isDarkTheme() else QColor(0, 0, 0)
self.nameLabel.setStyleSheet('QLabel{color: '+color.name()+'}')
setFont(self.logoutButton, 13)
self.setFixedSize(307, 82)
self.avatar.setRadius(24)
self.avatar.move(2, 6)
self.nameLabel.move(64, 13)
self.emailLabel.move(64, 32)
self.logoutButton.move(52, 48)
# coding:utf-8
import sys
from PyQt5 import QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QColor
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout
from qfluentwidgets import (RoundMenu, FluentIcon, Action, AvatarWidget, BodyLabel,
HyperlinkButton, CaptionLabel, setFont, setTheme, Theme, isDarkTheme)
class ProfileCard(QWidget):
""" Profile card """
def __init__(self, avatarPath: str, name: str, email: str, parent=None):
super().__init__(parent=parent)
self.avatar = AvatarWidget(avatarPath, self)
self.nameLabel = BodyLabel(name, self)
self.emailLabel = CaptionLabel(email, self)
self.logoutButton = HyperlinkButton(
'https://github.com/zhiyiYo/QMaterialWidgets', '注销', self)
color = QColor(206, 206, 206) if isDarkTheme() else QColor(96, 96, 96)
self.emailLabel.setStyleSheet('QLabel{color: '+color.name()+'}')
color = QColor(255, 255, 255) if isDarkTheme() else QColor(0, 0, 0)
self.nameLabel.setStyleSheet('QLabel{color: '+color.name()+'}')
setFont(self.logoutButton, 13)
self.setFixedSize(307, 82)
self.avatar.setRadius(24)
self.avatar.move(2, 6)
self.nameLabel.move(64, 13)
self.emailLabel.move(64, 32)
self.logoutButton.move(52, 48)
class Demo(QWidget):
def __init__(self):
super().__init__()
# setTheme(Theme.DARK)
# self.setStyleSheet('Demo{background: rgb(32, 32, 32)}')
self.setStyleSheet('Demo{background: white}')
self.setLayout(QHBoxLayout())
self.label = BodyLabel('Right-click your mouse', self)
self.label.setAlignment(Qt.AlignCenter)
setFont(self.label, 18)
self.layout().addWidget(self.label)
self.resize(400, 400)
def contextMenuEvent(self, e) -> None:
menu = RoundMenu(parent=self)
# add custom widget
card = ProfileCard('resource/shoko.png', '硝子酱', 'shokokawaii@outlook.com', menu)
menu.addWidget(card, selectable=False)
# menu.addWidget(card, selectable=True, onClick=lambda: print('666'))
menu.addSeparator()
menu.addActions([
Action(FluentIcon.PEOPLE, '管理账户和设置'),
Action(FluentIcon.SHOPPING_CART, '支付方式'),
Action(FluentIcon.CODE, '兑换代码和礼品卡'),
])
menu.addSeparator()
menu.addAction(Action(FluentIcon.SETTING, '设置'))
menu.exec(e.globalPos())
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_()
...@@ -228,7 +228,8 @@ class MenuActionListWidget(QListWidget): ...@@ -228,7 +228,8 @@ class MenuActionListWidget(QListWidget):
for i in range(self.count()): for i in range(self.count()):
item = self.item(i) item = self.item(i)
item.setSizeHint(item.sizeHint().width(), height) if not self.itemWidget(item):
item.setSizeHint(item.sizeHint().width(), height)
self._itemHeight = height self._itemHeight = height
self.adjustSize() self.adjustSize()
...@@ -356,6 +357,37 @@ class RoundMenu(QMenu): ...@@ -356,6 +357,37 @@ class RoundMenu(QMenu):
self.view.addItem(item) self.view.addItem(item)
self.adjustSize() self.adjustSize()
def addWidget(self, widget: QWidget, selectable=True, onClick=None):
""" add custom widget
Parameters
----------
widget: QWidget
custom widget
selectable: bool
whether the menu item is selectable
onClick: callable
the slot connected to item clicked signal
"""
action = QAction()
action.setProperty('selectable', selectable)
item = self._createActionItem(action)
item.setSizeHint(widget.size())
self.view.addItem(item)
self.view.setItemWidget(item, widget)
if not selectable:
item.setFlags(Qt.NoItemFlags)
if onClick:
action.triggered.connect(onClick)
self.adjustSize()
def _createActionItem(self, action: QAction, before=None): def _createActionItem(self, action: QAction, before=None):
""" create menu action item """ """ create menu action item """
if not before: if not before:
...@@ -560,10 +592,13 @@ class RoundMenu(QMenu): ...@@ -560,10 +592,13 @@ class RoundMenu(QMenu):
self.adjustSize() self.adjustSize()
def _onItemClicked(self, item): def _onItemClicked(self, item):
action = item.data(Qt.UserRole) action = item.data(Qt.UserRole) # type: QAction
if action not in self._actions or not action.isEnabled(): if action not in self._actions or not action.isEnabled():
return return
if self.view.itemWidget(item) and not action.property('selectable'):
return
self._hideMenu(False) self._hideMenu(False)
if not self.isSubMenu: if not self.isSubMenu:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册