229 lines
7.8 KiB
Python
229 lines
7.8 KiB
Python
# 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()
|