Salome HOME
New generic 2D View based on Qt
[modules/gui.git] / tools / CurvePlot / src / python / pyqtside / pyside_dynamic.py
1 """
2     How to load a user interface dynamically with PySide.
3     .. moduleauthor::  Sebastian Wiesner  <lunaryorn@gmail.com>
4 """
5 from PySide.QtCore import Slot, QMetaObject
6 from PySide.QtUiTools import QUiLoader
7
8 class UiLoader(QUiLoader):
9     """
10     Subclass :class:`~PySide.QtUiTools.QUiLoader` to create the user interface
11     in a base instance.
12
13     Unlike :class:`~PySide.QtUiTools.QUiLoader` itself this class does not
14     create a new instance of the top-level widget, but creates the user
15     interface in an existing instance of the top-level class.
16
17     This mimics the behaviour of :func:`PyQt5.uic.loadUi`.
18     """
19     def __init__(self, baseinstance, customWidgets=None):
20         """
21         Create a loader for the given ``baseinstance``.
22
23         The user interface is created in ``baseinstance``, which must be an
24         instance of the top-level class in the user interface to load, or a
25         subclass thereof.
26
27         ``customWidgets`` is a dictionary mapping from class name to class object
28         for widgets that you've promoted in the Qt Designer interface. Usually,
29         this should be done by calling registerCustomWidget on the QUiLoader, but
30         with PySide 1.1.2 on Ubuntu 12.04 x86_64 this causes a segfault.
31
32         ``parent`` is the parent object of this loader.
33         """
34         QUiLoader.__init__(self, baseinstance)
35         self.baseinstance = baseinstance
36         self.customWidgets = customWidgets
37
38     def createWidget(self, class_name, parent=None, name=''):
39         """
40         Function that is called for each widget defined in ui file,
41         overridden here to populate baseinstance instead.
42         """
43         if parent is None and self.baseinstance:
44             return self.baseinstance
45         else:
46             if class_name in self.availableWidgets():
47                 # create a new widget for child widgets
48                 widget = QUiLoader.createWidget(self, class_name, parent, name)
49             else:
50                 try:
51                     widget = self.customWidgets[class_name](parent)
52                 except (TypeError, KeyError) as e:
53                     raise Exception('No custom widget ' + class_name + ' found in customWidgets param of UiLoader __init__.')
54
55             if self.baseinstance:
56                 setattr(self.baseinstance, name, widget)
57
58             return widget
59
60 def loadUi(uifile, baseinstance=None, customWidgets=None):
61     """
62     Dynamically load a user interface from the given ``uifile``.
63     ``uifile`` is a string containing a file name of the UI file to load.
64
65     If ``baseinstance`` is ``None``, the a new instance of the top-level widget
66     will be created.  Otherwise, the user interface is created within the given
67     ``baseinstance``.  In this case ``baseinstance`` must be an instance of the
68     top-level widget class in the UI file to load, or a subclass thereof. .
69
70     ``customWidgets`` is a dictionary mapping from class name to class object
71     for widgets that you've promoted in the Qt Designer interface. Usually,
72     this should be done by calling registerCustomWidget on the QUiLoader, but
73     with PySide 1.1.2 on Ubuntu 12.04 x86_64 this causes a segfault.
74
75     :method:`~PySide.QtCore.QMetaObject.connectSlotsByName()` is called on the
76     created user interface, so you can implemented your slots according to its
77     conventions in your widget class.
78
79     Return ``baseinstance``, if ``baseinstance`` is not ``None``.  Otherwise
80     return the newly created instance of the user interface.
81     """
82
83     loader = UiLoader(baseinstance, customWidgets)
84     widget = loader.load(uifile)
85     QMetaObject.connectSlotsByName(widget)
86     return widget