Files

229 lines
7.8 KiB
Python
Raw Permalink Normal View History

2025-08-14 18:45:16 +08:00
# coding:utf-8
import sys
from PySide6.QtCore import Qt, Signal, QEasingCurve, QUrl
from PySide6.QtGui import QIcon, QDesktopServices
from PySide6.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QApplication, QFrame, QWidget
from qfluentwidgets import (NavigationBar, NavigationItemPosition, NavigationWidget, MessageBox,
isDarkTheme, setTheme, Theme, setThemeColor, SearchLineEdit,
PopUpAniStackedWidget, getFont)
from qfluentwidgets import FluentIcon as FIF
from qframelesswindow import FramelessWindow, TitleBar
class Widget(QWidget):
def __init__(self, text: str, parent=None):
super().__init__(parent=parent)
self.label = QLabel(text, self)
self.label.setAlignment(Qt.AlignCenter)
self.hBoxLayout = QHBoxLayout(self)
self.hBoxLayout.addWidget(self.label, 1, Qt.AlignCenter)
self.setObjectName(text.replace(' ', '-'))
class StackedWidget(QFrame):
""" Stacked widget """
currentChanged = Signal(int)
def __init__(self, parent=None):
super().__init__(parent=parent)
self.hBoxLayout = QHBoxLayout(self)
self.view = PopUpAniStackedWidget(self)
self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
self.hBoxLayout.addWidget(self.view)
self.view.currentChanged.connect(self.currentChanged)
def addWidget(self, widget):
""" add widget to view """
self.view.addWidget(widget)
def widget(self, index: int):
return self.view.widget(index)
def setCurrentWidget(self, widget, popOut=False):
if not popOut:
self.view.setCurrentWidget(widget, duration=300)
else:
self.view.setCurrentWidget(
widget, True, False, 200, QEasingCurve.InQuad)
def setCurrentIndex(self, index, popOut=False):
self.setCurrentWidget(self.view.widget(index), popOut)
class CustomTitleBar(TitleBar):
""" Title bar with icon and title """
def __init__(self, parent):
super().__init__(parent)
self.setFixedHeight(48)
self.hBoxLayout.removeWidget(self.minBtn)
self.hBoxLayout.removeWidget(self.maxBtn)
self.hBoxLayout.removeWidget(self.closeBtn)
# add window icon
self.iconLabel = QLabel(self)
self.iconLabel.setFixedSize(18, 18)
self.hBoxLayout.insertSpacing(0, 20)
self.hBoxLayout.insertWidget(
1, self.iconLabel, 0, Qt.AlignLeft | Qt.AlignVCenter)
self.window().windowIconChanged.connect(self.setIcon)
# add title label
self.titleLabel = QLabel(self)
self.hBoxLayout.insertWidget(
2, self.titleLabel, 0, Qt.AlignLeft | Qt.AlignVCenter)
self.titleLabel.setObjectName('titleLabel')
self.window().windowTitleChanged.connect(self.setTitle)
# add search line edit
self.searchLineEdit = SearchLineEdit(self)
self.searchLineEdit.setPlaceholderText('搜索应用、游戏、电影、设备等')
self.searchLineEdit.setFixedWidth(400)
self.searchLineEdit.setClearButtonEnabled(True)
self.vBoxLayout = QVBoxLayout()
self.buttonLayout = QHBoxLayout()
self.buttonLayout.setSpacing(0)
self.buttonLayout.setContentsMargins(0, 0, 0, 0)
self.buttonLayout.setAlignment(Qt.AlignTop)
self.buttonLayout.addWidget(self.minBtn)
self.buttonLayout.addWidget(self.maxBtn)
self.buttonLayout.addWidget(self.closeBtn)
self.vBoxLayout.addLayout(self.buttonLayout)
self.vBoxLayout.addStretch(1)
self.hBoxLayout.addLayout(self.vBoxLayout, 0)
def setTitle(self, title):
self.titleLabel.setText(title)
self.titleLabel.adjustSize()
def setIcon(self, icon):
self.iconLabel.setPixmap(QIcon(icon).pixmap(18, 18))
def resizeEvent(self, e):
self.searchLineEdit.move((self.width() - self.searchLineEdit.width()) //2, 8)
class Window(FramelessWindow):
def __init__(self):
super().__init__()
self.setTitleBar(CustomTitleBar(self))
# use dark theme mode
# setTheme(Theme.DARK)
# change the theme color
# setThemeColor('#0078d4')
self.hBoxLayout = QHBoxLayout(self)
self.navigationBar = NavigationBar(self)
self.stackWidget = StackedWidget(self)
# create sub interface
self.homeInterface = Widget('Home Interface', self)
self.appInterface = Widget('Application Interface', self)
self.videoInterface = Widget('Video Interface', self)
self.libraryInterface = Widget('library Interface', self)
# initialize layout
self.initLayout()
# add items to navigation interface
self.initNavigation()
self.initWindow()
def initLayout(self):
self.hBoxLayout.setSpacing(0)
self.hBoxLayout.setContentsMargins(0, 48, 0, 0)
self.hBoxLayout.addWidget(self.navigationBar)
self.hBoxLayout.addWidget(self.stackWidget)
self.hBoxLayout.setStretchFactor(self.stackWidget, 1)
def initNavigation(self):
self.addSubInterface(self.homeInterface, FIF.HOME, '主页', selectedIcon=FIF.HOME_FILL)
self.addSubInterface(self.appInterface, FIF.APPLICATION, '应用')
self.addSubInterface(self.videoInterface, FIF.VIDEO, '视频')
self.addSubInterface(self.libraryInterface, FIF.BOOK_SHELF, '', NavigationItemPosition.BOTTOM, FIF.LIBRARY_FILL)
self.navigationBar.addItem(
routeKey='Help',
icon=FIF.HELP,
text='帮助',
onClick=self.showMessageBox,
selectable=False,
position=NavigationItemPosition.BOTTOM,
)
self.stackWidget.currentChanged.connect(self.onCurrentInterfaceChanged)
self.navigationBar.setCurrentItem(self.homeInterface.objectName())
# hide the text of button when selected
# self.navigationBar.setSelectedTextVisible(False)
# adjust the font size of button
# self.navigationBar.setFont(getFont(12))
def initWindow(self):
self.resize(900, 700)
self.setWindowIcon(QIcon(':/qfluentwidgets/images/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 addSubInterface(self, interface, icon, text: str, position=NavigationItemPosition.TOP, selectedIcon=None):
""" add sub interface """
self.stackWidget.addWidget(interface)
self.navigationBar.addItem(
routeKey=interface.objectName(),
icon=icon,
text=text,
onClick=lambda: self.switchTo(interface),
selectedIcon=selectedIcon,
position=position,
)
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.navigationBar.setCurrentItem(widget.objectName())
def showMessageBox(self):
w = MessageBox(
'支持作者🥰',
'个人开发不易,如果这个项目帮助到了您,可以考虑请作者喝一瓶快乐水🥤。您的支持就是作者开发和维护项目的动力🚀',
self
)
w.yesButton.setText('来啦老弟')
w.cancelButton.setText('下次一定')
if w.exec():
QDesktopServices.openUrl(QUrl("https://afdian.net/a/zhiyiYo"))
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
w.show()
app.exec()