I'm migrating some code from PtQy5 to PySide6. I'm experiencing a significant behavioural difference when loading .ui files. The original PyQt5 code: import sys import os from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QWidget, QMainWindow from PyQt5 import uic ui_content = '<?xml version="1.0" encoding="UTF-8"?>\ <ui version="4.0">\ <class>Form</class>\ <widget class="QWidget" name="Form">\ <layout class="QVBoxLayout" name="verticalLayout">\ <item>\ <widget class="QPushButton" name="myButton">\ <property name="text">\ <string>PushButton</string>\ </property>\ </widget>\ </item>\ </layout>\ </widget>\ <resources/>\ <connections/>\ </ui>\ ' if __name__ == '__main__': app = QApplication(sys.argv) mainWindow = QMainWindow() class MyCentralWidget(QWidget): def __init__(self): super().__init__() import tempfile tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(ui_content.encode()) tmp.close() self.ui = uic.loadUi(tmp.name,self) self.ui.myButton.setText(self.ui.myButton.text() + " Foo") self.myButton.setText(self.myButton.text() + " Bar") os.remove(tmp.name) centralWidget = MyCentralWidget() mainWindow.setCentralWidget(centralWidget) mainWindow.show() app.exec() As you can see, objects declared in the .ui (like myButton) end up being both attributes of the returned ui object and the MyCentralWidget object. Meaning that both self.ui.myButton and self.myButton work. This is because I pass self as second parameter to loadUi, but if I don't do this the widget remains blank, so I suppose that's the right way to do. When migrating to PySide6, I had to adapt a bit the code: import sys import os from PySide6.QtWidgets import QApplication from PySide6.QtWidgets import QWidget, QMainWindow, QVBoxLayout from PySide6.QtUiTools import QUiLoader from PySide6.QtCore import QFile ui_content = '<?xml version="1.0" encoding="UTF-8"?>\ <ui version="4.0">\ <class>Form</class>\ <widget class="QWidget" name="Form">\ <layout class="QVBoxLayout" name="verticalLayout">\ <item>\ <widget class="QPushButton" name="myButton">\ <property name="text">\ <string>PushButton</string>\ </property>\ </widget>\ </item>\ </layout>\ </widget>\ <resources/>\ <connections/>\ </ui>\ ' if __name__ == '__main__': ui_loader = QUiLoader() app = QApplication(sys.argv) mainWindow = QMainWindow() class MyCentralWidget(QWidget): def __init__(self): super().__init__() import tempfile tmp = tempfile.NamedTemporaryFile(delete=False) tmp.write(ui_content.encode()) tmp.close() uifile = QFile(tmp.name) uifile.open(QFile.ReadOnly) self.ui = ui_loader.load(uifile,self) uifile.close() # Needed to have self.ui be centered self.mainLayout = QVBoxLayout(self) self.mainLayout.addWidget(self.ui) self.ui.myButton.setText(self.ui.myButton.text() + " Foo") #self.myButton does not exist #self.myButton.setText(self.myButton.text() + " Bar") os.remove(tmp.name) centralWidget = MyCentralWidget() mainWindow.setCentralWidget(centralWidget) mainWindow.show() app.exec() But now, the objects are not cloned to self and so self.myButton does not exist. Is that expected? Or am I doing something wrong? My code was written using PyQt5, so there's many places where we use self.XXX instead of self.ui.XXX just because it used to work just fine, and it's hard to identify all the places. To fix all the runtime issues, we duplicate the objects: self.__dict__.update(self.ui.__dict__) Is this a bad idea/workaround? Continue reading...