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;
}
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
add a comment |
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
add a comment |
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
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
python pyqt pyqt4 pyqt5
edited Nov 16 '18 at 15:14
eyllanesc
87.5k103564
87.5k103564
asked Aug 5 '16 at 7:48
fredrikfredrik
3,19353869
3,19353869
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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
.
add a comment |
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)
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
.
add a comment |
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
.
add a comment |
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
.
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
.
answered Aug 5 '16 at 17:48
ekhumoroekhumoro
78.4k15117194
78.4k15117194
add a comment |
add a comment |
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)
add a comment |
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)
add a comment |
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)
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)
edited Nov 28 '18 at 6:04
answered Nov 16 '18 at 14:55
EzR1d3rEzR1d3r
877
877
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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