Есть два основных отличия:
- с точки зрения загрузки, QUiLoader теоретически добавляет немного накладных расходов, поскольку он должен каждый раз создавать пользовательский интерфейс, что означает, что он должен анализировать XML-файл, создавать структуру узлов, а затем создавать пользовательский интерфейс со всем его содержимым; вместо этого файл uic напрямую создает пользовательский интерфейс, пропуская первые два шага выше;
- Загрузчик может создать только новый виджет на основе файла пользовательского интерфейса, в то время как метод uic позволяет использовать уже существующий базовый виджет, а дочерние виджеты могут быть добавлены к нему;
Последний момент, вероятно, является наиболее важным: используя QUiLoader, вы не можете напрямую использовать подклассы для загруженного пользовательского интерфейса.
Например, если вы создадите главное окно в конструкторе, QUiLoader вернет новое QMainWindow. Вы не можете (или, по крайней мере, не должны) делать следующее:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
ui_file = QFile("mainwindow.ui")
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
window = loader.load(ui_file, self)
И вы даже не должны пытаться сделать возвращаемый объект центральным виджетом, как показано ниже:
self.setCentralWidget(window)
потому что результатом было бы наличие QMainWindow внутри QMainWindow, что не рекомендуется и не поддерживается, а также может создать проблемы при использовании стандартных функций QMainWindow (как правило, доков и панелей инструментов).
Единственной альтернативой было бы создать виджет базовой формы в конструкторе и использовать его в качестве центрального виджета, с недостатком, что меню, доки и панели инструментов должны создаваться с помощью кода.
Для PySide единственная возможность, позволяющая создать полный подкласс,-это использовать метод pyside-uic, а затем в конечном итоге использовать множественное наследование (но это не является обязательным требованием, так как композиция в любом случае является допустимой альтернативой).:
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
С другой стороны, PyQt обеспечивает loadUi
функция, которая на самом деле делает то, что setupUi
делает, так как вторым аргументом является не родительский виджет, а сам виджет, и содержимое пользовательского интерфейса будет загружено в него:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi("mainwindow.ui", self)
Насколько я знаю, PySide пока не предоставляет ничего подобного.
Обратите внимание, что загрузка пользовательского интерфейса во время выполнения в любом случае имеет две проблемы, и для обеих привязок:
- нет предварительной проверки на вменяемость, если файл пользовательского интерфейса поврежден или недействителен, или имеет неподдерживаемые функции/свойства из-за несоответствия версий, он может загружаться неправильно или даже аварийно завершиться;
- при использовании IDE для объектов пользовательского интерфейса не выполняется завершение кода, так как они загружаются только во время выполнения;
Это не основные проблемы, но в любом случае важно знать о них.