Я использую QUiLoader pyside2 для загрузки таких файлов пользовательского интерфейса:
class MyWidget(QtWidgets.QWidget):
def make(*, text, parent=None):
loader = QUiLoader()
loader.registerCustomWidget(MyWidget)
w = loader.load("MyWidget.ui", parent)
QtCore.QMetaObject.connectSlotsByName(w)
w.conf(text=text)
return w
def conf(self, text):
self.label.setText(text)
Я могу вызвать w = MyWidget.make("Hello World!")
, и виджет загружается правильно, и текст установлен.
Теперь Я хочу использовать этот настраиваемый виджет в другом виджете:
class OuterWidget(QtWidgets.QWidget):
def make(*, text, parent=None):
loader = QUiLoader()
loader.registerCustomWidget(OuterWidget)
loader.registerCustomWidget(MyWidget)
w = loader.load("OuterWidget.ui", parent)
QtCore.QMetaObject.connectSlotsByName(w)
w.conf(text=text)
return w
def conf(self, text):
self.myWidget.conf(text)
Но нет возможности вызвать MyWidget.make
для создания виджета, а файл MyWidget.ui не будет использоваться для создания виджета .
Итак, как мне использовать QUiLoader с пользовательскими виджетами, которые сами содержат файлы пользовательского интерфейса?
Я пробовал перегрузить QUiLoader.createWidget
:
class Loader(QUiLoader):
def createWidget(self, className, parent=None, name=""):
logger.info(__("createWidget({0}, parent={1}, name={2})", className, parent, name))
if className == "MyWidget":
w = MyWidget.make(text="Hello World!", parent=parent)
w.setObjectName(name)
return w
else:
return super().createWidget(className, parent=parent, name=name)
Это затем выводится сообщение журнала:
2020-05-26 15: 27: 36,392 INFO OuterWidget createWidget (OuterWidget, parent = None, name = outerWidget)
и python3 умирает с кодом выхода 139.
app.py
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtUiTools import QUiLoader
class MyWidget(QtWidgets.QWidget):
def make(*, text, parent=None):
loader = QUiLoader()
loader.registerCustomWidget(MyWidget)
w = loader.load("MyWidget.ui", parent)
QtCore.QMetaObject.connectSlotsByName(w)
w.conf(text=text)
return w
def conf(self, text):
self.label.setText(text)
class OuterWidget(QtWidgets.QWidget):
def make(*, text, parent=None):
class Loader(QUiLoader):
def createWidget(self, className, parent=None, name=""):
if className == "MyWidget":
w = MyWidget.make(text="Hello World!", parent=parent)
w.setObjectName(name)
return w
else:
w = super().createWidget(className, parent=parent, name=name)
return w
#loader = QUiLoader()
loader = Loader()
loader.registerCustomWidget(OuterWidget)
loader.registerCustomWidget(MyWidget)
w = loader.load("OuterWidget.ui", parent)
QtCore.QMetaObject.connectSlotsByName(w)
w.conf(text=text)
return w
def conf(self, text):
self.myWidget.conf(text)
def main():
app = QtWidgets.QApplication(sys.argv)
app.setOrganizationName("Name")
app.setOrganizationDomain("Domain")
app.setApplicationName("App")
#w = MyWidget.make(text="Hello World!")
w = OuterWidget.make(text="Hello World!")
w.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
MyWidget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MyWidget</class>
<widget class="MyWidget" name="MyWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>MyWidget</class>
<extends>QWidget</extends>
<header>MyWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
OuterWidget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>outerWidget</class>
<widget class="OuterWidget" name="outerWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="MyWidget" name="myWidget" native="true">
<property name="geometry">
<rect>
<x>140</x>
<y>150</y>
<width>120</width>
<height>80</height>
</rect>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>MyWidget</class>
<extends>QWidget</extends>
<header>MyWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>OuterWidget</class>
<extends>QWidget</extends>
<header>OuterWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>