Search code examples
pythonpyqt5qt-designer

PyQt Navigation Bar Only Displays First Subinterface


This is my first time using QfluentWidgets to create a nice UI in PyQT. Currently, there is a problem with the navigation bar, which only shows InterfaceT1. The remaining three subinterfaces are not visible, even though they are implemented in separate UI files. However, any UI file can be displayed if it is placed before others.

Here are the ui files and demo.py for reproducing the problem. Run the code to get the result as mentioned above.

Here is the structure of my application: 1.ui 2.ui 3.ui 4.ui demo.py icon.png

## 1.ui ##
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>640</width>
    <height>480</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <widget class="DisplayLabel" name="DisplayLabel">
     <property name="text">
      <string>#1</string>   ## Different strings were set in each ui file.
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>DisplayLabel</class>
   <extends>QLabel</extends>
   <header>qfluentwidgets</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>
## demo.py ##

from qfluentwidgets import (NavigationItemPosition, MessageBox, setTheme, Theme, MSFluentWindow)
import sys, os
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from qfluentwidgets import *
FIF = FluentIcon
from PyQt5 import QtWidgets, uic

current_theme = Theme.LIGHT

if getattr(sys, 'frozen', False):
    RELATIVE_PATH = os.path.dirname(sys.executable)
else:
    RELATIVE_PATH = os.path.dirname(__file__)

def get_resource_path(filename):
    return os.path.join(RELATIVE_PATH, filename)

class Widget1(QtWidgets.QWidget):
    def __init__(self):
        super(Widget1, self).__init__()
        uic.loadUi((get_resource_path("1.ui")), self)
        
class Widget2(QtWidgets.QWidget):
    
    def __init__(self):
        super(Widget2, self).__init__()
        uic.loadUi((get_resource_path("2.ui")), self)
        
class Widget3(QtWidgets.QWidget):
    
    def __init__(self):
        super(Widget3, self).__init__()
        uic.loadUi((get_resource_path("3.ui")), self)

class Widget4(QtWidgets.QWidget):
    
    def __init__(self):
        super(Widget4, self).__init__()
        uic.loadUi((get_resource_path("4.ui")), self)

class Window(MSFluentWindow):
    def __init__(self):
        super().__init__()
        self.InterfaceT1 = Widget1()
        self.InterfaceT2 = Widget2()
        self.InterfaceT3 = Widget3()
        self.InterfaceT4 = Widget4()
        self.initNavigation()
        self.initWindow()

    def initNavigation(self):
        self.addSubInterface(self.InterfaceT1, FIF.QUICK_NOTE, '#1')
        self.addSubInterface(self.InterfaceT2, FIF.DEVELOPER_TOOLS, '#2')
        self.addSubInterface(self.InterfaceT3, FIF.RINGER, '#3')
        self.InterfaceT2.setObjectName("InterfaceT2")
        self.addSubInterface(self.InterfaceT4, FIF.BOOK_SHELF, '#4', FIF.LIBRARY_FILL, NavigationItemPosition.BOTTOM)
        self.navigationInterface.addItem(
            routeKey='About',
            icon=FIF.INFO,
            text='About',
            onClick=lambda: self.showMessageBox('About', 'The quick brown fox jumps over the lazy dog.'),
            selectable=False,
            position=NavigationItemPosition.BOTTOM,
        )

        self.navigationInterface.setCurrentItem(self.InterfaceT1.objectName())

        self.navigationInterface.addItem(
        routeKey='Help',
        icon=FIF.HELP,
        text='Help',
        onClick=lambda: self.showMessageBox('Help', 'The quick brown fox jumps over the lazy dog.'),
        selectable=False,
        position=NavigationItemPosition.BOTTOM,
        )

    def initWindow(self):
        self.resize(900, 700)
        self.setWindowIcon(QIcon(get_resource_path("icon.png")))
        self.setWindowTitle('Demo')

        desktop = QApplication.desktop().availableGeometry()
        w, h = desktop.width(), desktop.height()
        self.move(w//2 - self.width()//2, h//2 - self.height()//2)

    def showMessageBox(self, message, content):
        w = MessageBox(
            message,
            content,
            self
        )
        w.yesButton.setText('Ok')
        w.cancelButton.setText('Cancel')

        if w.exec():
            pass

    def closeEvent(self, event):
        print("Closing...")
        event.accept()
        os._exit(0)

if __name__ == '__main__':
    QApplication.setHighDpiScaleFactorRoundingPolicy(Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    
    setTheme(Theme.DARK)
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    app.exec_()

So how do I get all the subinterfaces to show up correctly in the navigation bar?


Solution

  • Because all root widget of your UI files have same name. Change your UI files. Change all <widget class="QWidget" name="Form"> lines in your UI files as:

    1.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form1">
     ...
    

    2.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form2">
     ...
    

    3.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form3">
     ...
    

    4.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form4">
     ...