Closed sciolism-9 closed 7 months ago
给当前 导航栏a 添加 子栏b ,再在这个 子栏b 中添加 子栏c ,然后点击回到 导航栏a ,更新子栏b 为子栏B,再在 子栏B 中更新 子栏c 为 子栏C ,此时在子栏C页面按下导航栏的返回按钮,发现没有回到子栏B,而是回到子栏b
https://github.com/zhiyiYo/PyQt-Fluent-Widgets/assets/67938359/4b5e1d44-3908-4741-b9d1-2ea12c45da60
Windows10
3.8.18 64bit
pyqt 5.15.10
v1.5.1
添加子栏
def add_first_subInterface(self, value_list): if not self.first_subInterface == None: self.navigationInterface.removeWidget( self.first_subInterface.objectName()) self.first_subInterface = value_list[0] icon = value_list[1] text = value_list[2] position = NavigationItemPosition.SCROLL self.stackWidget.addWidget(self.first_subInterface) self.first_subInterface.add_interface.connect( self.add_second_subInterface) self.navigationInterface.addItem( routeKey=self.first_subInterface.objectName(), icon=icon, text=text, onClick=lambda: self.switchTo(self.first_subInterface), position=position, tooltip=text, parentRouteKey=self.folderInterface.objectName() ) self.navigationInterface.widget( self.first_subInterface.objectName()).click()
# coding:utf-8 import sys from PyQt5.QtCore import Qt, QRect, QUrl, pyqtSignal from PyQt5.QtGui import QIcon, QPainter, QImage, QBrush, QColor, QFont, QDesktopServices from PyQt5.QtWidgets import QApplication, QFrame, QStackedWidget, QHBoxLayout, QLabel from qfluentwidgets import (NavigationInterface, NavigationItemPosition, NavigationWidget, MessageBox, LineEdit, PushButton, isDarkTheme, setTheme, Theme, qrouter) from qfluentwidgets import FluentIcon as FIF from qframelesswindow import FramelessWindow, TitleBar # 导航栏a class Widget(QFrame): add_interface = pyqtSignal(list) def __init__(self, text: str, parent=None): super().__init__(parent=parent) self.setObjectName("widget") self.label = LineEdit(self) self.label.setText(text) self.label.adjustSize() self.label.setAlignment(Qt.AlignCenter) self.btn = PushButton("click", self) self.hBoxLayout = QHBoxLayout(self) self.hBoxLayout.addWidget(self.label, 1, Qt.AlignCenter) self.hBoxLayout.addWidget(self.btn, 1, Qt.AlignCenter) self.btn.clicked.connect(self.send) # leave some space for title bar self.hBoxLayout.setContentsMargins(0, 32, 0, 0) def send(self): w = Widget_2("first_"+self.label.text()) self.add_interface.emit( [w, FIF.FOLDER, "first_"+self.label.text()]) # 子栏b、B class Widget_2(QFrame): add_interface = pyqtSignal(list) def __init__(self, text: str, parent=None): super().__init__(parent=parent) self.setObjectName("widget_2") self.label = LineEdit(self) self.label.setText(text) self.label.adjustSize() self.label.setAlignment(Qt.AlignCenter) self.btn = PushButton("click", self) self.hBoxLayout = QHBoxLayout(self) self.hBoxLayout.addWidget(self.label, 1, Qt.AlignCenter) self.hBoxLayout.addWidget(self.btn, 1, Qt.AlignCenter) self.btn.clicked.connect(self.send) # leave some space for title bar self.hBoxLayout.setContentsMargins(0, 32, 0, 0) def send(self): w = Widget_3("second_"+self.label.text()) self.add_interface.emit( [w, FIF.FOLDER, "second_"+self.label.text()]) # 子栏c、C class Widget_3(QFrame): add_interface = pyqtSignal(list) def __init__(self, text: str, parent=None): super().__init__(parent=parent) self.setObjectName("widget_3") self.label = LineEdit(self) self.label.setText(text) self.label.adjustSize() self.label.setAlignment(Qt.AlignCenter) self.hBoxLayout = QHBoxLayout(self) self.hBoxLayout.addWidget(self.label, 1, Qt.AlignCenter) # leave some space for title bar self.hBoxLayout.setContentsMargins(0, 32, 0, 0) class AvatarWidget(NavigationWidget): """ Avatar widget """ def __init__(self, parent=None): super().__init__(isSelectable=False, parent=parent) self.avatar = QImage('resource/logo.png').scaled( 24, 24, Qt.KeepAspectRatio, Qt.SmoothTransformation) def paintEvent(self, e): painter = QPainter(self) painter.setRenderHints( QPainter.SmoothPixmapTransform | QPainter.Antialiasing) painter.setPen(Qt.NoPen) if self.isPressed: painter.setOpacity(0.7) # draw background if self.isEnter: c = 255 if isDarkTheme() else 0 painter.setBrush(QColor(c, c, c, 10)) painter.drawRoundedRect(self.rect(), 5, 5) # draw avatar painter.setBrush(QBrush(self.avatar)) painter.translate(8, 6) painter.drawEllipse(0, 0, 24, 24) painter.translate(-8, -6) if not self.isCompacted: painter.setPen(Qt.white if isDarkTheme() else Qt.black) font = QFont('Segoe UI') font.setPixelSize(14) painter.setFont(font) painter.drawText(QRect(44, 0, 255, 36), Qt.AlignVCenter, 'zhiyiYo') class CustomTitleBar(TitleBar): """ Title bar with icon and title """ def __init__(self, parent): super().__init__(parent) # add window icon self.iconLabel = QLabel(self) self.iconLabel.setFixedSize(18, 18) self.hBoxLayout.insertSpacing(0, 10) self.hBoxLayout.insertWidget( 1, self.iconLabel, 0, Qt.AlignLeft | Qt.AlignBottom) self.window().windowIconChanged.connect(self.setIcon) # add title label self.titleLabel = QLabel(self) self.hBoxLayout.insertWidget( 2, self.titleLabel, 0, Qt.AlignLeft | Qt.AlignBottom) self.titleLabel.setObjectName('titleLabel') self.window().windowTitleChanged.connect(self.setTitle) def setTitle(self, title): self.titleLabel.setText(title) self.titleLabel.adjustSize() def setIcon(self, icon): self.iconLabel.setPixmap(QIcon(icon).pixmap(18, 18)) class Window(FramelessWindow): def __init__(self): super().__init__() self.setTitleBar(CustomTitleBar(self)) self.hBoxLayout = QHBoxLayout(self) self.navigationInterface = NavigationInterface( self, showMenuButton=True, showReturnButton=True) self.stackWidget = QStackedWidget(self) # create sub interface self.folderInterface = Widget('1', self) self.folderInterface.add_interface.connect(self.add_first_subInterface) self.first_subInterface = None self.second_subInterface = None self.settingInterface = Widget('Setting 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, 0, 0, 0) self.hBoxLayout.addWidget(self.navigationInterface) self.hBoxLayout.addWidget(self.stackWidget) self.hBoxLayout.setStretchFactor(self.stackWidget, 1) self.titleBar.raise_() self.navigationInterface.displayModeChanged.connect( self.titleBar.raise_) def initNavigation(self): self.navigationInterface.addSeparator() # add navigation items to scroll area self.addSubInterface(self.folderInterface, FIF.FOLDER, 'Folder library', NavigationItemPosition.SCROLL) # add custom widget to bottom self.navigationInterface.addWidget( routeKey='avatar', widget=AvatarWidget(), onClick=self.showMessageBox, position=NavigationItemPosition.BOTTOM ) self.addSubInterface(self.settingInterface, FIF.SETTING, 'Settings', NavigationItemPosition.BOTTOM) qrouter.setDefaultRouteKey( self.stackWidget, self.folderInterface.objectName()) self.stackWidget.currentChanged.connect(self.onCurrentInterfaceChanged) self.stackWidget.setCurrentIndex(0) def initWindow(self): self.resize(900, 700) self.setWindowIcon(QIcon('resource/logo.png')) self.setWindowTitle('PyQt-Fluent-Widgets') self.titleBar.setAttribute(Qt.WA_StyledBackground) desktop = QApplication.desktop().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): """ add sub interface """ self.stackWidget.addWidget(interface) self.navigationInterface.addItem( routeKey=interface.objectName(), icon=icon, text=text, onClick=lambda: self.switchTo(interface), position=position, tooltip=text ) def add_first_subInterface(self, value_list): if not self.first_subInterface == None: self.navigationInterface.removeWidget( self.first_subInterface.objectName()) self.first_subInterface = value_list[0] icon = value_list[1] text = value_list[2] position = NavigationItemPosition.SCROLL self.stackWidget.addWidget(self.first_subInterface) self.first_subInterface.add_interface.connect( self.add_second_subInterface) self.navigationInterface.addItem( routeKey=self.first_subInterface.objectName(), icon=icon, text=text, onClick=lambda: self.switchTo(self.first_subInterface), position=position, tooltip=text, parentRouteKey=self.folderInterface.objectName() ) self.navigationInterface.update() self.navigationInterface.widget( self.first_subInterface.objectName()).click() def add_second_subInterface(self, value_list): if not self.second_subInterface == None: self.navigationInterface.removeWidget( self.second_subInterface.objectName()) self.second_subInterface = value_list[0] icon = value_list[1] text = value_list[2] position = NavigationItemPosition.SCROLL self.stackWidget.addWidget(self.second_subInterface) self.navigationInterface.addItem( routeKey=self.second_subInterface.objectName(), icon=icon, text=text, onClick=lambda: self.switchTo(self.second_subInterface), position=position, tooltip=text, parentRouteKey=self.first_subInterface.objectName() ) self.navigationInterface.widget( self.second_subInterface.objectName()).click() 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()) qrouter.push(self.stackWidget, 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")) def resizeEvent(self, e): self.titleBar.move(46, 0) self.titleBar.resize(self.width()-46, self.titleBar.height()) if __name__ == '__main__': QApplication.setHighDpiScaleFactorRoundingPolicy( Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) app = QApplication(sys.argv) w = Window() w.show() app.exec_()
解决方法,每次更新子栏前因为需要实例化对应界面,在objectName添加时间戳来区分:self.first_subInterface.setObjectName(f"{self.firstsubInterface.objectName()}{time.time()}")
What happened?
给当前 导航栏a 添加 子栏b ,再在这个 子栏b 中添加 子栏c ,然后点击回到 导航栏a ,更新子栏b 为子栏B,再在 子栏B 中更新 子栏c 为 子栏C ,此时在子栏C页面按下导航栏的返回按钮,发现没有回到子栏B,而是回到子栏b
https://github.com/zhiyiYo/PyQt-Fluent-Widgets/assets/67938359/4b5e1d44-3908-4741-b9d1-2ea12c45da60
Operation System
Windows10
Python Version
3.8.18 64bit
PyQt/PySide Version
pyqt 5.15.10
PyQt/PySide-Fluent-Widgets Version
v1.5.1
How to Reproduce?
添加子栏
Minimum code