Files
fluent_widgets_pyside6/examples/navigation/navigation3/demo.py
2025-08-14 18:45:16 +08:00

191 lines
6.5 KiB
Python

# coding:utf-8
import sys
from PySide6.QtCore import Qt, QEvent
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QApplication, QStackedWidget, QHBoxLayout, QLabel, QWidget, QVBoxLayout
from qfluentwidgets import (NavigationInterface, NavigationItemPosition, NavigationWidget, MessageBox,
isDarkTheme, setTheme, Theme, setThemeColor, NavigationToolButton, NavigationPanel)
from qfluentwidgets import FluentIcon as FIF
from qframelesswindow import FramelessWindow, StandardTitleBar
class Widget(QWidget):
def __init__(self, text: str, parent=None):
super().__init__(parent=parent)
self.label = QLabel(text, self)
self.hBoxLayout = QHBoxLayout(self)
self.label.setAlignment(Qt.AlignCenter)
self.hBoxLayout.addWidget(self.label, 1, Qt.AlignCenter)
self.setObjectName(text.replace(' ', '-'))
class NavigationBar(QWidget):
""" Navigation widget """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.hBoxLayout = QHBoxLayout(self)
self.menuButton = NavigationToolButton(FIF.MENU, self)
self.navigationPanel = NavigationPanel(parent, True)
self.titleLabel = QLabel(self)
self.navigationPanel.move(0, 31)
self.hBoxLayout.setContentsMargins(5, 5, 5, 5)
self.hBoxLayout.addWidget(self.menuButton)
self.hBoxLayout.addWidget(self.titleLabel)
self.menuButton.clicked.connect(self.showNavigationPanel)
self.navigationPanel.setExpandWidth(260)
self.navigationPanel.setMenuButtonVisible(True)
self.navigationPanel.hide()
# enable acrylic effect
self.navigationPanel.setAcrylicEnabled(True)
self.window().installEventFilter(self)
def setTitle(self, title: str):
self.titleLabel.setText(title)
self.titleLabel.adjustSize()
def showNavigationPanel(self):
self.navigationPanel.show()
self.navigationPanel.raise_()
self.navigationPanel.expand()
def addItem(self, routeKey, icon, text: str, onClick, selectable=True, position= NavigationItemPosition.TOP):
def wrapper():
onClick()
self.setTitle(text)
self.navigationPanel.addItem(
routeKey, icon, text, wrapper, selectable, position)
def addSeparator(self, position=NavigationItemPosition.TOP):
self.navigationPanel.addSeparator(position)
def setCurrentItem(self, routeKey: str):
self.navigationPanel.setCurrentItem(routeKey)
self.setTitle(self.navigationPanel.widget(routeKey).text())
def eventFilter(self, obj, e: QEvent):
if obj is self.window():
if e.type() == QEvent.Resize:
self.navigationPanel.setFixedHeight(e.size().height() - 31)
return super().eventFilter(obj, e)
class Window(FramelessWindow):
def __init__(self):
super().__init__()
self.setTitleBar(StandardTitleBar(self))
# use dark theme mode
# setTheme(Theme.DARK)
# change the theme color
# setThemeColor('#0078d4')
self.vBoxLayout = QVBoxLayout(self)
self.navigationInterface = NavigationBar(self)
self.stackWidget = QStackedWidget(self)
# create sub interface
self.searchInterface = Widget('Search Interface', self)
self.musicInterface = Widget('Music Interface', self)
self.videoInterface = Widget('Video Interface', self)
self.folderInterface = Widget('Folder Interface', self)
self.settingInterface = Widget('Setting Interface', self)
self.stackWidget.addWidget(self.searchInterface)
self.stackWidget.addWidget(self.musicInterface)
self.stackWidget.addWidget(self.videoInterface)
self.stackWidget.addWidget(self.folderInterface)
self.stackWidget.addWidget(self.settingInterface)
# initialize layout
self.initLayout()
# add items to navigation interface
self.initNavigation()
self.initWindow()
def initLayout(self):
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setContentsMargins(0, self.titleBar.height(), 0, 0)
self.vBoxLayout.addWidget(self.navigationInterface)
self.vBoxLayout.addWidget(self.stackWidget)
self.vBoxLayout.setStretchFactor(self.stackWidget, 1)
def initNavigation(self):
self.addSubInterface(self.searchInterface, FIF.SEARCH, 'Search')
self.addSubInterface(self.musicInterface, FIF.MUSIC, 'Music library')
self.addSubInterface(self.videoInterface, FIF.VIDEO, 'Video library')
self.navigationInterface.addSeparator()
# add navigation items to scroll area
self.addSubInterface(self.folderInterface, FIF.FOLDER, 'Folder library', NavigationItemPosition.SCROLL)
# add item to bottom
self.addSubInterface(self.settingInterface, FIF.SETTING, 'Settings', NavigationItemPosition.BOTTOM)
self.stackWidget.currentChanged.connect(self.onCurrentInterfaceChanged)
self.stackWidget.setCurrentIndex(1)
def addSubInterface(self, w: QWidget, icon, text, position=NavigationItemPosition.TOP):
self.stackWidget.addWidget(w)
self.navigationInterface.addItem(
routeKey=w.objectName(),
icon=icon,
text=text,
onClick=lambda: self.switchTo(w),
position=position
)
def initWindow(self):
self.resize(500, 600)
self.setWindowIcon(QIcon('resource/logo.png'))
self.setWindowTitle('PyQt-Fluent-Widgets')
self.titleBar.setAttribute(Qt.WA_StyledBackground)
desktop = QApplication.screens()[0].availableGeometry()
w, h = desktop.width(), desktop.height()
self.move(w//2 - self.width()//2, h//2 - self.height()//2)
self.setQss()
def setQss(self):
color = 'dark' if isDarkTheme() else 'light'
with open(f'resource/{color}/demo.qss', encoding='utf-8') as f:
self.setStyleSheet(f.read())
def switchTo(self, widget):
self.stackWidget.setCurrentWidget(widget)
def onCurrentInterfaceChanged(self, index):
widget = self.stackWidget.widget(index)
self.navigationInterface.setCurrentItem(widget.objectName())
def showMessageBox(self):
w = MessageBox(
'This is a help message',
'You clicked a customized navigation widget. You can add more custom widgets by calling `NavigationInterface.addWidget()` 😉',
self
)
w.exec()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
w.show()
app.exec()