How to use custom widget and uic.loadUi without importing custom widget class package?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















Using PyQt4's uic.loadUi, I’d like to load a .ui file and use a custom widget in it. This means using the third package argument of uic.loadUi which will import the package with the custom widget's class inside.



However, I wish to define the custom widget's class in the same file as where I'm calling uic.loadUi. I’m trying to achieve this like so:



class MyCustomClass(QtWidgets.QPushButton):
""" This is my custom class for my custom widget """
def __init__(self, *args):
QtWidgets.QPushButton.__init__(self, *args)

...

sys.modules['mycustompackage'] = MyCustomClass
uic.loadUi('my_ui.ui', self, 'mycustompackage') # Loads .ui file which contains the MyCustomWidget widget


However, this returns the following error:



AttributeError: type object 'MyCustomClass' has no attribute 'MyCustomWidget'


Is there anything I could do to make this actually work? I suspect that MyCustomClass isn't defined in the manner uic.loadUi expects it.



In Qt Designer, I've promoted MyCustomWidget:



<?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="MyCustomWidget" name="customWidget">
<property name="geometry">
<rect>
<x>50</x>
<y>70</y>
<width>113</width>
<height>32</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>MyCustomWidget</class>
<extends>QPushButton</extends>
<header>MyCustomClass</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>




Solution



I solved it using the above .ui file like this:



class MyCustomClasses(object):
class MyCustomWidget(QtWidgets.QPushButton):
def __init__(self, *args):
QtWidgets.QPushButton.__init__(self, *args)

...

sys.modules['MyCustomClasses'] = MyCustomClasses
uic.loadUi('my_ui.ui', self) # Loads .ui file which contains MyCustomWidget









share|improve this question































    1















    Using PyQt4's uic.loadUi, I’d like to load a .ui file and use a custom widget in it. This means using the third package argument of uic.loadUi which will import the package with the custom widget's class inside.



    However, I wish to define the custom widget's class in the same file as where I'm calling uic.loadUi. I’m trying to achieve this like so:



    class MyCustomClass(QtWidgets.QPushButton):
    """ This is my custom class for my custom widget """
    def __init__(self, *args):
    QtWidgets.QPushButton.__init__(self, *args)

    ...

    sys.modules['mycustompackage'] = MyCustomClass
    uic.loadUi('my_ui.ui', self, 'mycustompackage') # Loads .ui file which contains the MyCustomWidget widget


    However, this returns the following error:



    AttributeError: type object 'MyCustomClass' has no attribute 'MyCustomWidget'


    Is there anything I could do to make this actually work? I suspect that MyCustomClass isn't defined in the manner uic.loadUi expects it.



    In Qt Designer, I've promoted MyCustomWidget:



    <?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="MyCustomWidget" name="customWidget">
    <property name="geometry">
    <rect>
    <x>50</x>
    <y>70</y>
    <width>113</width>
    <height>32</height>
    </rect>
    </property>
    <property name="text">
    <string>PushButton</string>
    </property>
    </widget>
    </widget>
    <widget class="QMenuBar" name="menubar">
    <property name="geometry">
    <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>22</height>
    </rect>
    </property>
    </widget>
    <widget class="QStatusBar" name="statusbar"/>
    </widget>
    <customwidgets>
    <customwidget>
    <class>MyCustomWidget</class>
    <extends>QPushButton</extends>
    <header>MyCustomClass</header>
    </customwidget>
    </customwidgets>
    <resources/>
    <connections/>
    </ui>




    Solution



    I solved it using the above .ui file like this:



    class MyCustomClasses(object):
    class MyCustomWidget(QtWidgets.QPushButton):
    def __init__(self, *args):
    QtWidgets.QPushButton.__init__(self, *args)

    ...

    sys.modules['MyCustomClasses'] = MyCustomClasses
    uic.loadUi('my_ui.ui', self) # Loads .ui file which contains MyCustomWidget









    share|improve this question



























      1












      1








      1








      Using PyQt4's uic.loadUi, I’d like to load a .ui file and use a custom widget in it. This means using the third package argument of uic.loadUi which will import the package with the custom widget's class inside.



      However, I wish to define the custom widget's class in the same file as where I'm calling uic.loadUi. I’m trying to achieve this like so:



      class MyCustomClass(QtWidgets.QPushButton):
      """ This is my custom class for my custom widget """
      def __init__(self, *args):
      QtWidgets.QPushButton.__init__(self, *args)

      ...

      sys.modules['mycustompackage'] = MyCustomClass
      uic.loadUi('my_ui.ui', self, 'mycustompackage') # Loads .ui file which contains the MyCustomWidget widget


      However, this returns the following error:



      AttributeError: type object 'MyCustomClass' has no attribute 'MyCustomWidget'


      Is there anything I could do to make this actually work? I suspect that MyCustomClass isn't defined in the manner uic.loadUi expects it.



      In Qt Designer, I've promoted MyCustomWidget:



      <?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="MyCustomWidget" name="customWidget">
      <property name="geometry">
      <rect>
      <x>50</x>
      <y>70</y>
      <width>113</width>
      <height>32</height>
      </rect>
      </property>
      <property name="text">
      <string>PushButton</string>
      </property>
      </widget>
      </widget>
      <widget class="QMenuBar" name="menubar">
      <property name="geometry">
      <rect>
      <x>0</x>
      <y>0</y>
      <width>800</width>
      <height>22</height>
      </rect>
      </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
      </widget>
      <customwidgets>
      <customwidget>
      <class>MyCustomWidget</class>
      <extends>QPushButton</extends>
      <header>MyCustomClass</header>
      </customwidget>
      </customwidgets>
      <resources/>
      <connections/>
      </ui>




      Solution



      I solved it using the above .ui file like this:



      class MyCustomClasses(object):
      class MyCustomWidget(QtWidgets.QPushButton):
      def __init__(self, *args):
      QtWidgets.QPushButton.__init__(self, *args)

      ...

      sys.modules['MyCustomClasses'] = MyCustomClasses
      uic.loadUi('my_ui.ui', self) # Loads .ui file which contains MyCustomWidget









      share|improve this question
















      Using PyQt4's uic.loadUi, I’d like to load a .ui file and use a custom widget in it. This means using the third package argument of uic.loadUi which will import the package with the custom widget's class inside.



      However, I wish to define the custom widget's class in the same file as where I'm calling uic.loadUi. I’m trying to achieve this like so:



      class MyCustomClass(QtWidgets.QPushButton):
      """ This is my custom class for my custom widget """
      def __init__(self, *args):
      QtWidgets.QPushButton.__init__(self, *args)

      ...

      sys.modules['mycustompackage'] = MyCustomClass
      uic.loadUi('my_ui.ui', self, 'mycustompackage') # Loads .ui file which contains the MyCustomWidget widget


      However, this returns the following error:



      AttributeError: type object 'MyCustomClass' has no attribute 'MyCustomWidget'


      Is there anything I could do to make this actually work? I suspect that MyCustomClass isn't defined in the manner uic.loadUi expects it.



      In Qt Designer, I've promoted MyCustomWidget:



      <?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="MyCustomWidget" name="customWidget">
      <property name="geometry">
      <rect>
      <x>50</x>
      <y>70</y>
      <width>113</width>
      <height>32</height>
      </rect>
      </property>
      <property name="text">
      <string>PushButton</string>
      </property>
      </widget>
      </widget>
      <widget class="QMenuBar" name="menubar">
      <property name="geometry">
      <rect>
      <x>0</x>
      <y>0</y>
      <width>800</width>
      <height>22</height>
      </rect>
      </property>
      </widget>
      <widget class="QStatusBar" name="statusbar"/>
      </widget>
      <customwidgets>
      <customwidget>
      <class>MyCustomWidget</class>
      <extends>QPushButton</extends>
      <header>MyCustomClass</header>
      </customwidget>
      </customwidgets>
      <resources/>
      <connections/>
      </ui>




      Solution



      I solved it using the above .ui file like this:



      class MyCustomClasses(object):
      class MyCustomWidget(QtWidgets.QPushButton):
      def __init__(self, *args):
      QtWidgets.QPushButton.__init__(self, *args)

      ...

      sys.modules['MyCustomClasses'] = MyCustomClasses
      uic.loadUi('my_ui.ui', self) # Loads .ui file which contains MyCustomWidget






      python pyqt pyqt4 pyqt5






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 16 '18 at 15:14









      eyllanesc

      87.5k103564




      87.5k103564










      asked Aug 5 '16 at 7:48









      fredrikfredrik

      3,19353869




      3,19353869
























          2 Answers
          2






          active

          oldest

          votes


















          1














          To quote from the documentation you linked to, the third argument of loadUi is:




          the optional package that is the base package for any relative imports of custom widgets [emphasis added]




          The actual module name that the custom class will be imported from must be specified in the ui file itself. In Qt Designer, this is achieved by setting the "Header file" to the appropriate value, and it will be stored in the <header> tags inside the ui file. Note that this value can be the fully qualified package path of the module (e.g. "pkg.mymodule") - in which case, it would not be necessary to use the third argument of loadUi. There should never be any need for sys.module hacks.



          The loadUi function is quite simple. It just generates a python module in exactly the same way that the command-line tool does, and then loads it using exec.






          share|improve this answer































            1














            The are three possible ways.
            For example, you have the module QtCustomWidgets.widgets.mybutton
            It is a files QtCustomWidgets/widgets/mybutton.py and QtCustomWidgets/python/mybuttonplugin.py in you project with MyButton class in it.



            First way define includeFile method from QtCustomWidgets/python/mybuttonplugin.py as:



            def includeFile(self):
            return "QtCustomWidgets.widgets.mybutton"


            Second way is to use uic.loadUi with packadge path:
            uic.loadUi('my_ui.ui', self, packadge='QtCustomWidgets.widgets')



            but you have to use the dot in you module names (includeFile is the method from QtCustomWidgets/python/mybuttonplugin.py ):



            def includeFile(self):
            return ".mybutton"


            , so in the header it must look like this:



            <customwidgets>
            <customwidget>
            <class>MyButton</class>
            <extends>QPushButton</extends>
            <header>.mybutton</header>
            </customwidget>
            </customwidgets>


            And result way still will be "QtCustomWidgets.widgets" + ".mybutton"



            There is the source PyQt code custom widget loader (qobjectcreator.py), you may find it yourself:



            class _CustomWidgetLoader(object):
            def __init__(self, package):
            # should it stay this way?
            if '.' not in sys.path:
            sys.path.append('.')

            self._widgets = {}
            self._modules = {}
            self._package = package

            def addCustomWidget(self, widgetClass, baseClass, module):
            assert widgetClass not in self._widgets
            self._widgets[widgetClass] = module

            def search(self, cls):
            module_name = self._widgets.get(cls)
            if module_name is None:
            return None

            module = self._modules.get(module_name)
            if module is None:
            if module_name.startswith('.'):
            if self._package == '':
            raise ImportError(
            "relative import of %s without base package specified" % module_name)

            if self._package.startswith('.'):
            raise ImportError(
            "base package %s is relative" % self._package)

            mname = self._package + module_name
            else:
            mname = module_name

            try:
            module = __import__(mname, {}, {}, (cls,))
            except ValueError:
            # Raise a more helpful exception.
            raise ImportError("unable to import module %s" % mname)

            self._modules[module_name] = module

            return getattr(module, cls)


            Third way:
            To add path to your widgets in sys.path (you have to be import sys):



            sys.path.append( "./QtCustomWidgets/widgets" )
            uic.loadUi('my_ui.ui', self)





            share|improve this answer


























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38783911%2fhow-to-use-custom-widget-and-uic-loadui-without-importing-custom-widget-class-pa%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1














              To quote from the documentation you linked to, the third argument of loadUi is:




              the optional package that is the base package for any relative imports of custom widgets [emphasis added]




              The actual module name that the custom class will be imported from must be specified in the ui file itself. In Qt Designer, this is achieved by setting the "Header file" to the appropriate value, and it will be stored in the <header> tags inside the ui file. Note that this value can be the fully qualified package path of the module (e.g. "pkg.mymodule") - in which case, it would not be necessary to use the third argument of loadUi. There should never be any need for sys.module hacks.



              The loadUi function is quite simple. It just generates a python module in exactly the same way that the command-line tool does, and then loads it using exec.






              share|improve this answer




























                1














                To quote from the documentation you linked to, the third argument of loadUi is:




                the optional package that is the base package for any relative imports of custom widgets [emphasis added]




                The actual module name that the custom class will be imported from must be specified in the ui file itself. In Qt Designer, this is achieved by setting the "Header file" to the appropriate value, and it will be stored in the <header> tags inside the ui file. Note that this value can be the fully qualified package path of the module (e.g. "pkg.mymodule") - in which case, it would not be necessary to use the third argument of loadUi. There should never be any need for sys.module hacks.



                The loadUi function is quite simple. It just generates a python module in exactly the same way that the command-line tool does, and then loads it using exec.






                share|improve this answer


























                  1












                  1








                  1







                  To quote from the documentation you linked to, the third argument of loadUi is:




                  the optional package that is the base package for any relative imports of custom widgets [emphasis added]




                  The actual module name that the custom class will be imported from must be specified in the ui file itself. In Qt Designer, this is achieved by setting the "Header file" to the appropriate value, and it will be stored in the <header> tags inside the ui file. Note that this value can be the fully qualified package path of the module (e.g. "pkg.mymodule") - in which case, it would not be necessary to use the third argument of loadUi. There should never be any need for sys.module hacks.



                  The loadUi function is quite simple. It just generates a python module in exactly the same way that the command-line tool does, and then loads it using exec.






                  share|improve this answer













                  To quote from the documentation you linked to, the third argument of loadUi is:




                  the optional package that is the base package for any relative imports of custom widgets [emphasis added]




                  The actual module name that the custom class will be imported from must be specified in the ui file itself. In Qt Designer, this is achieved by setting the "Header file" to the appropriate value, and it will be stored in the <header> tags inside the ui file. Note that this value can be the fully qualified package path of the module (e.g. "pkg.mymodule") - in which case, it would not be necessary to use the third argument of loadUi. There should never be any need for sys.module hacks.



                  The loadUi function is quite simple. It just generates a python module in exactly the same way that the command-line tool does, and then loads it using exec.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Aug 5 '16 at 17:48









                  ekhumoroekhumoro

                  78.4k15117194




                  78.4k15117194

























                      1














                      The are three possible ways.
                      For example, you have the module QtCustomWidgets.widgets.mybutton
                      It is a files QtCustomWidgets/widgets/mybutton.py and QtCustomWidgets/python/mybuttonplugin.py in you project with MyButton class in it.



                      First way define includeFile method from QtCustomWidgets/python/mybuttonplugin.py as:



                      def includeFile(self):
                      return "QtCustomWidgets.widgets.mybutton"


                      Second way is to use uic.loadUi with packadge path:
                      uic.loadUi('my_ui.ui', self, packadge='QtCustomWidgets.widgets')



                      but you have to use the dot in you module names (includeFile is the method from QtCustomWidgets/python/mybuttonplugin.py ):



                      def includeFile(self):
                      return ".mybutton"


                      , so in the header it must look like this:



                      <customwidgets>
                      <customwidget>
                      <class>MyButton</class>
                      <extends>QPushButton</extends>
                      <header>.mybutton</header>
                      </customwidget>
                      </customwidgets>


                      And result way still will be "QtCustomWidgets.widgets" + ".mybutton"



                      There is the source PyQt code custom widget loader (qobjectcreator.py), you may find it yourself:



                      class _CustomWidgetLoader(object):
                      def __init__(self, package):
                      # should it stay this way?
                      if '.' not in sys.path:
                      sys.path.append('.')

                      self._widgets = {}
                      self._modules = {}
                      self._package = package

                      def addCustomWidget(self, widgetClass, baseClass, module):
                      assert widgetClass not in self._widgets
                      self._widgets[widgetClass] = module

                      def search(self, cls):
                      module_name = self._widgets.get(cls)
                      if module_name is None:
                      return None

                      module = self._modules.get(module_name)
                      if module is None:
                      if module_name.startswith('.'):
                      if self._package == '':
                      raise ImportError(
                      "relative import of %s without base package specified" % module_name)

                      if self._package.startswith('.'):
                      raise ImportError(
                      "base package %s is relative" % self._package)

                      mname = self._package + module_name
                      else:
                      mname = module_name

                      try:
                      module = __import__(mname, {}, {}, (cls,))
                      except ValueError:
                      # Raise a more helpful exception.
                      raise ImportError("unable to import module %s" % mname)

                      self._modules[module_name] = module

                      return getattr(module, cls)


                      Third way:
                      To add path to your widgets in sys.path (you have to be import sys):



                      sys.path.append( "./QtCustomWidgets/widgets" )
                      uic.loadUi('my_ui.ui', self)





                      share|improve this answer






























                        1














                        The are three possible ways.
                        For example, you have the module QtCustomWidgets.widgets.mybutton
                        It is a files QtCustomWidgets/widgets/mybutton.py and QtCustomWidgets/python/mybuttonplugin.py in you project with MyButton class in it.



                        First way define includeFile method from QtCustomWidgets/python/mybuttonplugin.py as:



                        def includeFile(self):
                        return "QtCustomWidgets.widgets.mybutton"


                        Second way is to use uic.loadUi with packadge path:
                        uic.loadUi('my_ui.ui', self, packadge='QtCustomWidgets.widgets')



                        but you have to use the dot in you module names (includeFile is the method from QtCustomWidgets/python/mybuttonplugin.py ):



                        def includeFile(self):
                        return ".mybutton"


                        , so in the header it must look like this:



                        <customwidgets>
                        <customwidget>
                        <class>MyButton</class>
                        <extends>QPushButton</extends>
                        <header>.mybutton</header>
                        </customwidget>
                        </customwidgets>


                        And result way still will be "QtCustomWidgets.widgets" + ".mybutton"



                        There is the source PyQt code custom widget loader (qobjectcreator.py), you may find it yourself:



                        class _CustomWidgetLoader(object):
                        def __init__(self, package):
                        # should it stay this way?
                        if '.' not in sys.path:
                        sys.path.append('.')

                        self._widgets = {}
                        self._modules = {}
                        self._package = package

                        def addCustomWidget(self, widgetClass, baseClass, module):
                        assert widgetClass not in self._widgets
                        self._widgets[widgetClass] = module

                        def search(self, cls):
                        module_name = self._widgets.get(cls)
                        if module_name is None:
                        return None

                        module = self._modules.get(module_name)
                        if module is None:
                        if module_name.startswith('.'):
                        if self._package == '':
                        raise ImportError(
                        "relative import of %s without base package specified" % module_name)

                        if self._package.startswith('.'):
                        raise ImportError(
                        "base package %s is relative" % self._package)

                        mname = self._package + module_name
                        else:
                        mname = module_name

                        try:
                        module = __import__(mname, {}, {}, (cls,))
                        except ValueError:
                        # Raise a more helpful exception.
                        raise ImportError("unable to import module %s" % mname)

                        self._modules[module_name] = module

                        return getattr(module, cls)


                        Third way:
                        To add path to your widgets in sys.path (you have to be import sys):



                        sys.path.append( "./QtCustomWidgets/widgets" )
                        uic.loadUi('my_ui.ui', self)





                        share|improve this answer




























                          1












                          1








                          1







                          The are three possible ways.
                          For example, you have the module QtCustomWidgets.widgets.mybutton
                          It is a files QtCustomWidgets/widgets/mybutton.py and QtCustomWidgets/python/mybuttonplugin.py in you project with MyButton class in it.



                          First way define includeFile method from QtCustomWidgets/python/mybuttonplugin.py as:



                          def includeFile(self):
                          return "QtCustomWidgets.widgets.mybutton"


                          Second way is to use uic.loadUi with packadge path:
                          uic.loadUi('my_ui.ui', self, packadge='QtCustomWidgets.widgets')



                          but you have to use the dot in you module names (includeFile is the method from QtCustomWidgets/python/mybuttonplugin.py ):



                          def includeFile(self):
                          return ".mybutton"


                          , so in the header it must look like this:



                          <customwidgets>
                          <customwidget>
                          <class>MyButton</class>
                          <extends>QPushButton</extends>
                          <header>.mybutton</header>
                          </customwidget>
                          </customwidgets>


                          And result way still will be "QtCustomWidgets.widgets" + ".mybutton"



                          There is the source PyQt code custom widget loader (qobjectcreator.py), you may find it yourself:



                          class _CustomWidgetLoader(object):
                          def __init__(self, package):
                          # should it stay this way?
                          if '.' not in sys.path:
                          sys.path.append('.')

                          self._widgets = {}
                          self._modules = {}
                          self._package = package

                          def addCustomWidget(self, widgetClass, baseClass, module):
                          assert widgetClass not in self._widgets
                          self._widgets[widgetClass] = module

                          def search(self, cls):
                          module_name = self._widgets.get(cls)
                          if module_name is None:
                          return None

                          module = self._modules.get(module_name)
                          if module is None:
                          if module_name.startswith('.'):
                          if self._package == '':
                          raise ImportError(
                          "relative import of %s without base package specified" % module_name)

                          if self._package.startswith('.'):
                          raise ImportError(
                          "base package %s is relative" % self._package)

                          mname = self._package + module_name
                          else:
                          mname = module_name

                          try:
                          module = __import__(mname, {}, {}, (cls,))
                          except ValueError:
                          # Raise a more helpful exception.
                          raise ImportError("unable to import module %s" % mname)

                          self._modules[module_name] = module

                          return getattr(module, cls)


                          Third way:
                          To add path to your widgets in sys.path (you have to be import sys):



                          sys.path.append( "./QtCustomWidgets/widgets" )
                          uic.loadUi('my_ui.ui', self)





                          share|improve this answer















                          The are three possible ways.
                          For example, you have the module QtCustomWidgets.widgets.mybutton
                          It is a files QtCustomWidgets/widgets/mybutton.py and QtCustomWidgets/python/mybuttonplugin.py in you project with MyButton class in it.



                          First way define includeFile method from QtCustomWidgets/python/mybuttonplugin.py as:



                          def includeFile(self):
                          return "QtCustomWidgets.widgets.mybutton"


                          Second way is to use uic.loadUi with packadge path:
                          uic.loadUi('my_ui.ui', self, packadge='QtCustomWidgets.widgets')



                          but you have to use the dot in you module names (includeFile is the method from QtCustomWidgets/python/mybuttonplugin.py ):



                          def includeFile(self):
                          return ".mybutton"


                          , so in the header it must look like this:



                          <customwidgets>
                          <customwidget>
                          <class>MyButton</class>
                          <extends>QPushButton</extends>
                          <header>.mybutton</header>
                          </customwidget>
                          </customwidgets>


                          And result way still will be "QtCustomWidgets.widgets" + ".mybutton"



                          There is the source PyQt code custom widget loader (qobjectcreator.py), you may find it yourself:



                          class _CustomWidgetLoader(object):
                          def __init__(self, package):
                          # should it stay this way?
                          if '.' not in sys.path:
                          sys.path.append('.')

                          self._widgets = {}
                          self._modules = {}
                          self._package = package

                          def addCustomWidget(self, widgetClass, baseClass, module):
                          assert widgetClass not in self._widgets
                          self._widgets[widgetClass] = module

                          def search(self, cls):
                          module_name = self._widgets.get(cls)
                          if module_name is None:
                          return None

                          module = self._modules.get(module_name)
                          if module is None:
                          if module_name.startswith('.'):
                          if self._package == '':
                          raise ImportError(
                          "relative import of %s without base package specified" % module_name)

                          if self._package.startswith('.'):
                          raise ImportError(
                          "base package %s is relative" % self._package)

                          mname = self._package + module_name
                          else:
                          mname = module_name

                          try:
                          module = __import__(mname, {}, {}, (cls,))
                          except ValueError:
                          # Raise a more helpful exception.
                          raise ImportError("unable to import module %s" % mname)

                          self._modules[module_name] = module

                          return getattr(module, cls)


                          Third way:
                          To add path to your widgets in sys.path (you have to be import sys):



                          sys.path.append( "./QtCustomWidgets/widgets" )
                          uic.loadUi('my_ui.ui', self)






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 28 '18 at 6:04

























                          answered Nov 16 '18 at 14:55









                          EzR1d3rEzR1d3r

                          877




                          877






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38783911%2fhow-to-use-custom-widget-and-uic-loadui-without-importing-custom-widget-class-pa%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Xamarin.iOS Cant Deploy on Iphone

                              Glorious Revolution

                              Dulmage-Mendelsohn matrix decomposition in Python