initial fluent-widgets ui
This commit is contained in:
228
examples/navigation/navigation_bar/demo.py
Normal file
228
examples/navigation/navigation_bar/demo.py
Normal file
@ -0,0 +1,228 @@
|
||||
# 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()
|
||||
53
examples/navigation/navigation_bar/resource/dark/demo.qss
Normal file
53
examples/navigation/navigation_bar/resource/dark/demo.qss
Normal file
@ -0,0 +1,53 @@
|
||||
Widget > QLabel {
|
||||
font: 24px 'Segoe UI', 'Microsoft YaHei';
|
||||
}
|
||||
|
||||
StackedWidget {
|
||||
border: 1px solid rgb(29, 29, 29);
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
border-top-left-radius: 10px;
|
||||
background-color: rgb(39, 39, 39);
|
||||
}
|
||||
|
||||
Window {
|
||||
background-color: rgb(32, 32, 32);
|
||||
}
|
||||
|
||||
Widget > QLabel {
|
||||
color: white;
|
||||
}
|
||||
|
||||
CustomTitleBar {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
CustomTitleBar>QLabel#titleLabel {
|
||||
background: transparent;
|
||||
font: 13px 'Segoe UI';
|
||||
padding: 0 10px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
MinimizeButton {
|
||||
qproperty-normalColor: white;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
qproperty-hoverColor: white;
|
||||
qproperty-hoverBackgroundColor: rgba(255, 255, 255, 26);
|
||||
qproperty-pressedColor: white;
|
||||
qproperty-pressedBackgroundColor: rgba(255, 255, 255, 51)
|
||||
}
|
||||
|
||||
MaximizeButton {
|
||||
qproperty-normalColor: white;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
qproperty-hoverColor: white;
|
||||
qproperty-hoverBackgroundColor: rgba(255, 255, 255, 26);
|
||||
qproperty-pressedColor: white;
|
||||
qproperty-pressedBackgroundColor: rgba(255, 255, 255, 51)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
qproperty-normalColor: white;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
}
|
||||
46
examples/navigation/navigation_bar/resource/light/demo.qss
Normal file
46
examples/navigation/navigation_bar/resource/light/demo.qss
Normal file
@ -0,0 +1,46 @@
|
||||
Widget > QLabel {
|
||||
font: 24px 'Segoe UI', 'Microsoft YaHei';
|
||||
}
|
||||
|
||||
StackedWidget {
|
||||
border: 1px solid rgb(229, 229, 229);
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
border-top-left-radius: 10px;
|
||||
background-color: rgb(249, 249, 249);
|
||||
}
|
||||
|
||||
Window {
|
||||
background-color: rgb(243, 243, 243);
|
||||
}
|
||||
|
||||
CustomTitleBar>QLabel#titleLabel {
|
||||
color: black;
|
||||
background: transparent;
|
||||
font: 13px 'Segoe UI';
|
||||
padding: 0 10px
|
||||
}
|
||||
|
||||
MinimizeButton {
|
||||
qproperty-normalColor: black;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
qproperty-hoverColor: black;
|
||||
qproperty-hoverBackgroundColor: rgba(0, 0, 0, 26);
|
||||
qproperty-pressedColor: black;
|
||||
qproperty-pressedBackgroundColor: rgba(0, 0, 0, 51)
|
||||
}
|
||||
|
||||
|
||||
MaximizeButton {
|
||||
qproperty-normalColor: black;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
qproperty-hoverColor: black;
|
||||
qproperty-hoverBackgroundColor: rgba(0, 0, 0, 26);
|
||||
qproperty-pressedColor: black;
|
||||
qproperty-pressedBackgroundColor: rgba(0, 0, 0, 51)
|
||||
}
|
||||
|
||||
CloseButton {
|
||||
qproperty-normalColor: black;
|
||||
qproperty-normalBackgroundColor: transparent;
|
||||
}
|
||||
BIN
examples/navigation/navigation_bar/resource/shoko.png
Normal file
BIN
examples/navigation/navigation_bar/resource/shoko.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 262 KiB |
Reference in New Issue
Block a user