pythonuser-interfaceqt-designerpyqt6qt-design-studio

QUiLoader in PySide6 shows an empty window


Empty UI

enter image description here

The primary issue I have encountering involves integrating a custom UI designed with Qt Designer (or similar tools) into a PySide6-based Python application. The UI comprises a QMainWindow as the main window, containing a QTabWidget for tabbed navigation. Each tab within this QTabWidget is supposed to have a QScrollArea, allowing for scrollable content within each tab, which is especially useful for content that exceeds the visible area.

Upon attempting to run your PySide6 application to display the designed UI, you're facing a problem where the application window appears empty, without showing any of the designed UI elements such as tabs, scroll areas, tables, buttons, etc. Despite the application running without crashing or producing explicit errors indicating failure to load the UI file, the expected UI components do not appear in the application window.

I made sure the UI Loads and I can fetch object names within the UI However Nothing is Displaying.

import sys
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QFile, QIODevice
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
        QMetaObject, QObject, QPoint, QRect,
        QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
        QFont, QFontDatabase, QGradient, QIcon,
        QImage, QKeySequence, QLinearGradient, QPainter,
        QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QAbstractScrollArea, QApplication, QFrame, QGraphicsView,
        QHBoxLayout, QHeaderView, QLabel, QLineEdit,
        QMainWindow, QPushButton, QScrollArea, QSizePolicy,
        QStatusBar, QTabWidget, QTableView, QTableWidget,
        QTableWidgetItem, QVBoxLayout, QWidget)

class AppDemo(QMainWindow):
    def __init__(self):
        super(AppDemo, self).__init__()
        self.load_ui()

    def load_ui(self):
        loader = QUiLoader()
        ui_file = QFile('GUI v2.ui')
        if not ui_file.open(QIODevice.ReadOnly):
            print(f"Cannot open '{ui_file.fileName()}': {ui_file.errorString()}")
            sys.exit(-1)
        self.ui = loader.load(ui_file, self)
        ui_file.close()
        if not self.ui:
            print("Cannot load UI")
            sys.exit(-1)
        print("UI loaded successfully")
        button = self.ui.findChild(QPushButton, 'br_submit')
        if button:
            print(button.objectName())
        else:
            print("PushButton not found.")


        self.setCentralWidget(self.ui)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = AppDemo()
    window.show()
    sys.exit(app.exec())

here is the .ui file:

    <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1947</width>
    <height>3664</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <property name="minimumSize">
    <size>
     <width>0</width>
     <height>0</height>
    </size>
   </property>
   <widget class="QTabWidget" name="tabWidget">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>1911</width>
      <height>2231</height>
     </rect>
    </property>
    <property name="sizePolicy">
     <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
      <horstretch>0</horstretch>
      <verstretch>0</verstretch>
     </sizepolicy>
    </property>
    <property name="minimumSize">
     <size>
      <width>0</width>
      <height>0</height>
     </size>
    </property>
    <property name="toolTip">
     <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
    <property name="autoFillBackground">
     <bool>true</bool>
    </property>
    <property name="currentIndex">
     <number>11</number>
    </property>
    <widget class="QWidget" name="tab">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="whatsThis">
      <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
     </property>
     <attribute name="title">
      <string>BR Feasibility Summary</string>
     </attribute>
     <widget class="QFrame" name="br_input">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>80</y>
        <width>311</width>
        <height>201</height>
       </rect>
      </property>
      <property name="frameShape">
       <enum>QFrame::Shape::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Shadow::Raised</enum>
      </property>
     </widget>
     <widget class="QFrame" name="br_Output">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>340</y>
        <width>311</width>
        <height>481</height>
       </rect>
      </property>
      <property name="frameShape">
       <enum>QFrame::Shape::StyledPanel</enum>
      </property>
      <property name="frameShadow">
       <enum>QFrame::Shadow::Raised</enum>
      </property>
     </widget>
     <widget class="QScrollArea" name="scrollArea">
      <property name="geometry">
       <rect>
        <x>-1</x>
        <y>-1</y>
        <width>1171</width>
        <height>861</height>
       </rect>
      </property>
      <property name="widgetResizable">
       <bool>true</bool>
      </property>
      <widget class="QWidget" name="scrollAreaWidgetContents">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>1169</width>
         <height>859</height>
        </rect>
       </property>
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <widget class="QLabel" name="label">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>0</y>
          <width>241</width>
          <height>51</height>
         </rect>
        </property>
        <property name="text">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:16pt; font-weight:700; text-decoration: underline;&quot;&gt;BR Feasibility Summary&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
       <widget class="QTableView" name="br_input_table">
        <property name="geometry">
         <rect>
          <x>20</x>
          <y>60</y>
          <width>291</width>
          <height>181</height>
         </rect>
        </property>
        <property name="sizePolicy">
         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="sizeAdjustPolicy">
         <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
        </property>
        <property name="alternatingRowColors">
         <bool>true</bool>
        </property>
        <attribute name="horizontalHeaderVisible">
         <bool>true</bool>
        </attribute>
       </widget>
       <widget class="QPushButton" name="br_submit">
        <property name="geometry">
         <rect>
          <x>100</x>
          <y>260</y>
          <width>111</width>
          <height>41</height>
         </rect>
        </property>
        <property name="text">
         <string>Submit</string>
        </property>
       </widget>
       <widget class="QTableView" name="br_input_table_3">
        <property name="geometry">
         <rect>
          <x>20</x>
          <y>320</y>
          <width>291</width>
          <height>451</height>
         </rect>
        </property>
        <property name="sizePolicy">
         <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="sizeAdjustPolicy">
         <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents</enum>
        </property>
       </widget>
      </widget>
     </widget>
    </widget>
    <widget class="QWidget" name="assumptions1Tab">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <attribute name="title">
      <string>Assumptions 1</string>
     </attribute>
     <widget class="QScrollArea" name="scrollAreaAssumtions">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>1531</width>
        <height>781</height>
       </rect>
      </property>
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
      <property name="verticalScrollBarPolicy">
       <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOn</enum>
      </property>
      <property name="horizontalScrollBarPolicy">
       <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOn</enum>
      </property>
      <property name="sizeAdjustPolicy">
       <enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
      </property>
      <property name="widgetResizable">
       <bool>false</bool>
      </property>
      <widget class="QWidget" name="scrollAreaWidgetContents_2">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>1882</width>
         <height>2922</height>
        </rect>
       </property>
       <property name="sizePolicy">
        <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
         <horstretch>0</horstretch>
         <verstretch>0</verstretch>
        </sizepolicy>
       </property>
       <widget class="QLabel" name="label_64">
        <property name="geometry">
         <rect>
          <x>560</x>
          <y>2090</y>
          <width>142</width>
          <height>32</height>
         </rect>
        </property>
        <property name="maximumSize">
         <size>
          <width>150</width>
          <height>16777215</height>
         </size>
        </property>
        <property name="text">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;Energy / Fuel (USD / litre)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
       <widget class="QTableWidget" name="assumptionsTableMKLink_Boiklep">
        <property name="geometry">
         <rect>
          <x>0</x>
          <y>850</y>
          <width>1861</width>
          <height>71</height>
         </rect>
        </property>
       </widget>
       <widget class="QLabel" name="label_33">
        <property name="geometry">
         <rect>
          <x>690</x>
          <y>2320</y>
          <width>258</width>
          <height>16</height>
         </rect>
        </property>
        <property name="text">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:700;&quot;&gt;OPEX Escalation Value (% / annum from Year 7)&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
       </widget>
       <widget class="QLabel" name="label_83">
        <property name="geometry">
         <rect>
          <x>10</x>
          <y>2630</y>
          <width>108</width>
          <height>57</height>
         </rect>
        </property>
        <property name="sizePolicy">
         <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="text">
         <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt; font-weight:700;&quot;&gt;9) Revenue&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
        </property>
        <property name="margin">
         <number>20</number>
        </property>
       </widget>
       <widget class="QLabel" name="label_21">
        <property name="geometry">

Solution

  • DiSCLAIMER This solution will just make your code show the Window you expect. It is not the right way to use QUiLoader() :

    try removing : window.show() (that is the empty window you are seeing/showing)

    from:

    if __name__ == '__main__':
        app = QApplication(sys.argv)
        window = AppDemo()
        window.show()
        sys.exit(app.exec())
    

    and add after self.setCentralWidget(self.ui) in def load_ui(self) of class AppDemo(QMainWindow):

    this line:

    self.ui.show()

    see PySide2 QUiLoader returns an empty window for details :

    QUiLoader().load() returns the widget as an object so if you assign it to a variable it will not do anything, you should use show():

    Example from link above accepted answer :

    import sys
    from PySide2.QtWidgets import QApplication
    from PySide2 import QtUiTools
    
    app = QApplication(sys.argv)
    w = QtUiTools.QUiLoader().load("dialog1.ui")
    w.show()
    sys.exit(app.exec_())