pyside2 QUiLoader с настраиваемыми виджетами с файлами пользовательского интерфейса - PullRequest
0 голосов
/ 26 мая 2020

Я использую 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>
...