Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. PySide vs PyQt ui file load.
Forum Updated to NodeBB v4.3 + New Features

PySide vs PyQt ui file load.

Scheduled Pinned Locked Moved Unsolved Qt for Python
pyside
8 Posts 3 Posters 577 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    swoiwode
    wrote on last edited by
    #1

    Why does PySide ui load differ from PyQt? I'd like to use PySide since it is 'official' and has (hopefully) a more robust update cycle. Code fragments highlight the issue. Thanks, Scott

    PyQt6 ui or py files work and matches my development flow.
    PySide6 py file works, ui file fails here with:
    File "...\qt_test.py", line 53, in event_loop
    print(self.label.text())
    ^^^^^^^^^^
    AttributeError: 'main' object has no attribute 'label'

    Minimal ui:
    qt_mainwindow.ui -> default 'Main Window' and a label. DT Widget Designer v6.82
    pyuic6 qt_mainwindow.ui -o qt_mainwindow_pyqt6.py
    pyuic6 qt_mainwindow.ui -o qt_mainwindow_pyside6.py
    """
    class main(PySide6.QtWidgets.QMainWindow, Ui_MainWindow):
    def init(self, ui_file_flag, ui_file):
    super(main, self).init()
    if ui_file_flag:
    print('loading ui_file file')
    # PyQt6.uic.loadUi(ui_file, self)
    # both PySide6 ui loads fail at the same place and with the same message (line-53)
    # PySide6.QtUiTools.loadUiType(ui_file)
    PySide6.QtUiTools.QUiLoader().load(ui_file)
    else:
    print('loading py file')
    self.setupUi(self)

    jsulmJ 1 Reply Last reply
    0
    • S swoiwode

      Why does PySide ui load differ from PyQt? I'd like to use PySide since it is 'official' and has (hopefully) a more robust update cycle. Code fragments highlight the issue. Thanks, Scott

      PyQt6 ui or py files work and matches my development flow.
      PySide6 py file works, ui file fails here with:
      File "...\qt_test.py", line 53, in event_loop
      print(self.label.text())
      ^^^^^^^^^^
      AttributeError: 'main' object has no attribute 'label'

      Minimal ui:
      qt_mainwindow.ui -> default 'Main Window' and a label. DT Widget Designer v6.82
      pyuic6 qt_mainwindow.ui -o qt_mainwindow_pyqt6.py
      pyuic6 qt_mainwindow.ui -o qt_mainwindow_pyside6.py
      """
      class main(PySide6.QtWidgets.QMainWindow, Ui_MainWindow):
      def init(self, ui_file_flag, ui_file):
      super(main, self).init()
      if ui_file_flag:
      print('loading ui_file file')
      # PyQt6.uic.loadUi(ui_file, self)
      # both PySide6 ui loads fail at the same place and with the same message (line-53)
      # PySide6.QtUiTools.loadUiType(ui_file)
      PySide6.QtUiTools.QUiLoader().load(ui_file)
      else:
      print('loading py file')
      self.setupUi(self)

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @swoiwode Where is this print statement in your code?
      You do not store what load(ui_file) returns anywhere - how are you going to use it?
      https://doc.qt.io/qtforpython-6/tutorials/basictutorial/uifiles.html

      Please format you code properly when posting.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      JonBJ 1 Reply Last reply
      1
      • jsulmJ jsulm

        @swoiwode Where is this print statement in your code?
        You do not store what load(ui_file) returns anywhere - how are you going to use it?
        https://doc.qt.io/qtforpython-6/tutorials/basictutorial/uifiles.html

        Please format you code properly when posting.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @jsulm , @swoiwode
        PySide6.QtUiTools.QUiLoader().load(ui_file) is the function to use. I presume the OP's issue is that he has existing code using PyQt6.uic.loadUi(ui_file, self), which loads into self while the PySide call instead returns some newly created widget? PySide and PyQt are mostly similar/identical, but I do not they do their dynamic loading of a .ui file differently. I don't know whether you can achieve same from PySide.

        Further, I only expected these dynamic loadings to produce a widget tree you can access via findChild<>(). But the existing code is apparently failing on some existing self.label.text() call. self.label must be a Python variable/reference label set to some QLabel found in the .ui file. I do not know how that gets set in the first place. Is it done explicitly somewhere in OP's code? Did I read that either or both of the respective PySide and PyQt calls actually do some uic running magic at runtime to (perhaps?) produce Python code with variables for the widgets in the .ui file? I think the OP needs to examine the documentation or code of the respective PySide/PyQt methods.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          swoiwode
          wrote on last edited by
          #4

          @JonB, @jsulm,
          Thanks for the replies. I will upload the complete code, ui file and format too.

          I was afraid that ui loading was one of the differences between PySide and PyQt, prior searches gave me that belief.

          BTW - Any non-functional print statements are my breadcrumbs :p. The development flow starts with a uniquely named ui file and template. Converted to py, so the ‘wiring’ can be confirmed. Then further GUI development is done with live user engagement/presence, rapid visuals of the GUI are needed and changes made as required. Converting ui to py, adjusting code as needed, passing through pyinstaller and checking functionality are done afterwards. I can deliver a solution within ~hour.

          Thanks, Scott

          1 Reply Last reply
          0
          • S Offline
            S Offline
            swoiwode
            wrote on last edited by
            #5

            @jsulm, @JonB
            Sample error message, python code and ui file, as requested.

            **** error message start ****

            C:\Users\Scott\Desktop\PythonDev\qt\.venv\Scripts\python.exe C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py -iuf .\qt_mainwindow.ui 
            Traceback (most recent call last):
              File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 70, in <module>
                window: PySide6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
                                                        ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
              File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 44, in __init__
                self.event_loop()
                ~~~~~~~~~~~~~~~^^
              File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 57, in event_loop
                print(self.label.text())
                      ^^^^^^^^^^
            AttributeError: 'main' object has no attribute 'label'
            

            **** error message end ****

            **** python code start ****

            """
            barebone implementations to load ui file for Pyside or PyQt, enable one or the other
            qt_mainwindow.ui -> default 'Main Window' and a label. DT Widget Designer v6.82
            
            This code should print 'TextLabel' to the console every second
            """
            import sys
            
            # ---- PyQt ---- comment/uncomment as needed
            # import PyQt6.QtWidgets
            # import PyQt6.uic
            # import PyQt6.QtGui
            # import PyQt6.QtCore
            
            # ---- PySide ---- comment/uncomment as needed
            import PySide6.QtWidgets
            import PySide6.QtUiTools
            import PySide6.QtGui
            import PySide6.QtCore
            
            # ---- PyQt ---- comment/uncomment as needed
            # from qt_mainwindow_pyqt6 import Ui_MainWindow
            
            # ---- PySide ---- comment/uncomment as needed
            from qt_mainwindow_pyside6 import Ui_MainWindow
            
            
            # ---- PyQt ---- comment/uncomment as needed
            # class main(PyQt6.QtWidgets.QMainWindow, Ui_MainWindow):
            
            # ---- PySide ---- comment/uncomment as needed
            class main(PySide6.QtWidgets.QMainWindow, Ui_MainWindow):
                def __init__(self, ui_file_flag, ui_file):
                    super(main, self).__init__()
                    if ui_file_flag:
                        # ---- PyQt ---- comment/uncomment as needed
                        # PyQt6.uic.loadUi(ui_file, self)
            
                        # ---- PySide ---- comment/uncomment as needed
                        PySide6.QtUiTools.QUiLoader().load(ui_file)
                    else:
                        self.setupUi(self)
            
                    self.event_loop()
            
                    # ---- PyQt ---- comment/uncomment as needed
                    # self.timer = PyQt6.QtCore.QTimer()
            
                    # ---- PySide ---- comment/uncomment as needed
                    self.timer = PySide6.QtCore.QTimer()
            
                    self.timer.timeout.connect(self.event_loop)  # noqa
                    self.timer.start(1000)
            
                # FAIL, PySide ui fiie for AttributeError: 'main' object has no attribute 'label'
                def event_loop(self) -> None:
                    print(self.label.text())
            
            
            if __name__ == '__main__':
                m_ui_file_flag: bool = True  # <- developer switch, False for release.
                m_ui_file = r'.\qt_mainwindow.ui'
            
                # ---- PyQt ---- comment/uncomment as needed
                # app = PyQt6.QtWidgets.QApplication(sys.argv)
                # window: PyQt6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
            
                # ---- PySide ---- comment/uncomment as needed
                app = PySide6.QtWidgets.QApplication(sys.argv)
                window: PySide6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
            
                window.show()
                sys.exit(app.exec())
            

            **** python code end ****

            **** ui code start ****

            <?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>800</width>
                <height>600</height>
               </rect>
              </property>
              <property name="windowTitle">
               <string>MainWindow</string>
              </property>
              <widget class="QWidget" name="centralwidget">
               <widget class="QLabel" name="label">
                <property name="geometry">
                 <rect>
                  <x>370</x>
                  <y>250</y>
                  <width>49</width>
                  <height>16</height>
                 </rect>
                </property>
                <property name="text">
                 <string>TextLabel</string>
                </property>
               </widget>
              </widget>
              <widget class="QMenuBar" name="menubar">
               <property name="geometry">
                <rect>
                 <x>0</x>
                 <y>0</y>
                 <width>800</width>
                 <height>33</height>
                </rect>
               </property>
              </widget>
              <widget class="QStatusBar" name="statusbar"/>
             </widget>
             <resources/>
             <connections/>
            </ui>
            

            **** ui code end ****

            JonBJ 1 Reply Last reply
            0
            • S swoiwode

              @jsulm, @JonB
              Sample error message, python code and ui file, as requested.

              **** error message start ****

              C:\Users\Scott\Desktop\PythonDev\qt\.venv\Scripts\python.exe C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py -iuf .\qt_mainwindow.ui 
              Traceback (most recent call last):
                File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 70, in <module>
                  window: PySide6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
                                                          ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
                File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 44, in __init__
                  self.event_loop()
                  ~~~~~~~~~~~~~~~^^
                File "C:\Users\Scott\Desktop\PythonDev\qt\qt_test.py", line 57, in event_loop
                  print(self.label.text())
                        ^^^^^^^^^^
              AttributeError: 'main' object has no attribute 'label'
              

              **** error message end ****

              **** python code start ****

              """
              barebone implementations to load ui file for Pyside or PyQt, enable one or the other
              qt_mainwindow.ui -> default 'Main Window' and a label. DT Widget Designer v6.82
              
              This code should print 'TextLabel' to the console every second
              """
              import sys
              
              # ---- PyQt ---- comment/uncomment as needed
              # import PyQt6.QtWidgets
              # import PyQt6.uic
              # import PyQt6.QtGui
              # import PyQt6.QtCore
              
              # ---- PySide ---- comment/uncomment as needed
              import PySide6.QtWidgets
              import PySide6.QtUiTools
              import PySide6.QtGui
              import PySide6.QtCore
              
              # ---- PyQt ---- comment/uncomment as needed
              # from qt_mainwindow_pyqt6 import Ui_MainWindow
              
              # ---- PySide ---- comment/uncomment as needed
              from qt_mainwindow_pyside6 import Ui_MainWindow
              
              
              # ---- PyQt ---- comment/uncomment as needed
              # class main(PyQt6.QtWidgets.QMainWindow, Ui_MainWindow):
              
              # ---- PySide ---- comment/uncomment as needed
              class main(PySide6.QtWidgets.QMainWindow, Ui_MainWindow):
                  def __init__(self, ui_file_flag, ui_file):
                      super(main, self).__init__()
                      if ui_file_flag:
                          # ---- PyQt ---- comment/uncomment as needed
                          # PyQt6.uic.loadUi(ui_file, self)
              
                          # ---- PySide ---- comment/uncomment as needed
                          PySide6.QtUiTools.QUiLoader().load(ui_file)
                      else:
                          self.setupUi(self)
              
                      self.event_loop()
              
                      # ---- PyQt ---- comment/uncomment as needed
                      # self.timer = PyQt6.QtCore.QTimer()
              
                      # ---- PySide ---- comment/uncomment as needed
                      self.timer = PySide6.QtCore.QTimer()
              
                      self.timer.timeout.connect(self.event_loop)  # noqa
                      self.timer.start(1000)
              
                  # FAIL, PySide ui fiie for AttributeError: 'main' object has no attribute 'label'
                  def event_loop(self) -> None:
                      print(self.label.text())
              
              
              if __name__ == '__main__':
                  m_ui_file_flag: bool = True  # <- developer switch, False for release.
                  m_ui_file = r'.\qt_mainwindow.ui'
              
                  # ---- PyQt ---- comment/uncomment as needed
                  # app = PyQt6.QtWidgets.QApplication(sys.argv)
                  # window: PyQt6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
              
                  # ---- PySide ---- comment/uncomment as needed
                  app = PySide6.QtWidgets.QApplication(sys.argv)
                  window: PySide6.QtWidgets.QMainWindow = main(m_ui_file_flag, m_ui_file)
              
                  window.show()
                  sys.exit(app.exec())
              

              **** python code end ****

              **** ui code start ****

              <?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>800</width>
                  <height>600</height>
                 </rect>
                </property>
                <property name="windowTitle">
                 <string>MainWindow</string>
                </property>
                <widget class="QWidget" name="centralwidget">
                 <widget class="QLabel" name="label">
                  <property name="geometry">
                   <rect>
                    <x>370</x>
                    <y>250</y>
                    <width>49</width>
                    <height>16</height>
                   </rect>
                  </property>
                  <property name="text">
                   <string>TextLabel</string>
                  </property>
                 </widget>
                </widget>
                <widget class="QMenuBar" name="menubar">
                 <property name="geometry">
                  <rect>
                   <x>0</x>
                   <y>0</y>
                   <width>800</width>
                   <height>33</height>
                  </rect>
                 </property>
                </widget>
                <widget class="QStatusBar" name="statusbar"/>
               </widget>
               <resources/>
               <connections/>
              </ui>
              

              **** ui code end ****

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @swoiwode
              As already said: your code has self.label.text(). How or where did self.label ever get created? Certainly it is not by PySide6.QtUiTools.QUiLoader().load(ui_file). So was it (somehow) created before by PyQt6.uic.loadUi(ui_file, self)? We don't know, it's a third party product. No, they are not the same. At some level they both load a .ui file, but what they then do is different and unknown for PyQt6.uic.loadUi().

              I suggested you examine its documentation and code if you want to understand what you would need to do from PySide. Just directly replacing one call with the other clearly does not work, as you have discovered.

              P.S.
              Read https://www.pythonguis.com/faq/pyqt5-vs-pyside2/ , UI files section. It's for PyQt5 vs PySide2, but it will be same for PyQt6 vs PySide6. It mentions "but you can work around this with a separate function" and gives some code. But I'm still not sure who that to relates to your existing usage of self.label.

              See also https://www.pythontutorial.net/pyqt/qt-designer/#using-ui-file-directly. And https://python-forum.io/thread-35619.html.

              I don't know where PyQt6.uic is documented? [Good luck tracking it down: the only instance in The Universe turns out to be https://riverbankcomputing.com/static/Docs/PyQt6/api/uic/uic-module.html#loadUi and goodness knows how you get there.]

              If by any chance that uic in its name indicates that it requires the PyQt6 equivalent of uic to be shipped and found at runtime, and that is run to generated Python code at runtime which is somehow imported and hence you can get a variable like label created at runtime, then I don't think PySide has an equivalent and you would have to change some of your code. [The preceding may not be the case at all, I am not sure where I might have seen that it might work like that.]

              Hmm, I think that https://python-forum.io/thread-35619.html may be key and the only docs I have seen so far. Someone says

              Is there any way to load ui with Pyside6 that the widgets become attributes of the class instead of attributes of another attribute of the class e.g. "self.ui"

              So that does imply that PySide6.QtUiTools.QUiLoader().load(ui_file) creates Python "attributes/variables" at runtime for named widgets in the .ui file (I still don't know where this behaviour is documented) and so does PyQt6.uic.loadUi(). The difference is that in PyQt you can put that directly into self via PyQt6.uic.loadUi(ui_file, self) whereas from PySide6.QtUiTools.QUiLoader().load(ui_file) you get back a "dummy" class you must use, like self.ui = PySide6.QtUiTools.QUiLoader().load(ui_file) and then you can access self.ui.label. I think you will need to change your code to work off self.ui where appropriate.

              FWIW, loading a .ui file into self.ui is the direct equivalent of the way it is done in this->ui from C++. In that sense the PySide interface follows this pattern while PyQt6.uic.loadUi(ui_file, self) is "non-standard".

              1 Reply Last reply
              1
              • S Offline
                S Offline
                swoiwode
                wrote on last edited by
                #7

                @JonB

                self.label
                

                comes from the .ui file.

                It is working now with

                self.ui = PySide6.QtUiTools.QUiLoader().load(ui_file)
                

                and using

                self.ui.label.text()
                

                will print 'TextLabel', ever second to the console.

                Adding

                self.ui.show()
                

                as the last line of

                __init__
                

                and removing

                window.show()
                

                in

                if __name__ == '__main__':
                

                Displays:
                Screenshot 2025-10-17 160249.png
                I will embrace this methodology going forward.

                Thanks, Scott

                JonBJ 1 Reply Last reply
                1
                • S swoiwode

                  @JonB

                  self.label
                  

                  comes from the .ui file.

                  It is working now with

                  self.ui = PySide6.QtUiTools.QUiLoader().load(ui_file)
                  

                  and using

                  self.ui.label.text()
                  

                  will print 'TextLabel', ever second to the console.

                  Adding

                  self.ui.show()
                  

                  as the last line of

                  __init__
                  

                  and removing

                  window.show()
                  

                  in

                  if __name__ == '__main__':
                  

                  Displays:
                  Screenshot 2025-10-17 160249.png
                  I will embrace this methodology going forward.

                  Thanks, Scott

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @swoiwode
                  Yes, you have made the right changes! Note how you changed from PyQt6.uic.loadUi(ui_file, self), which loaded into self and gave you self.label etc. over to self.ui = PySide6.QtUiTools.QUiLoader().load(ui_file), which returned into a newly created self.ui (or whatever you choose to call it) and hence gave you self.ui.label etc. It's just a different way of doing things, and PySide just does not offer that parameter or loading into self.

                  Looking around at what examples there are on the web I found that actually even in PyQt more people had worked from self.ui = PyQt6.uic.loadUi(ui_file) which is also available and similar to the PySide way than that "non-standard" PyQt6.uic.loadUi(ui_file, self) which the code you inherited had chosen to use.

                  Honestly you came across one of the few difference between PyQt and PySide right from the outset in the small script you were working on. 99% of the time you should find that same code simply works from PyQt to PySide.

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved