##// END OF EJS Templates
BUG: Explicitly merge the __init__ and __new__ metaclass methods for MetaQObjectHasTraits. The MetaHasTraits code was not being executed previously.
Robert Kern -
Show More
@@ -1,87 +1,106 b''
1 1 """ Defines miscellaneous Qt-related helper classes and functions.
2 2 """
3 3
4 # Standard library imports.
5 import inspect
6
4 7 # System library imports.
5 8 from PyQt4 import QtCore, QtGui
6 9
7 10 # IPython imports.
8 from IPython.utils.traitlets import HasTraits
11 from IPython.utils.traitlets import HasTraits, TraitType
9 12
10 13 #-----------------------------------------------------------------------------
11 14 # Metaclasses
12 15 #-----------------------------------------------------------------------------
13 16
14 17 MetaHasTraits = type(HasTraits)
15 18 MetaQObject = type(QtCore.QObject)
16 19
17 # You can switch the order of the parents here and it doesn't seem to matter.
18 20 class MetaQObjectHasTraits(MetaQObject, MetaHasTraits):
19 21 """ A metaclass that inherits from the metaclasses of HasTraits and QObject.
20 22
21 23 Using this metaclass allows a class to inherit from both HasTraits and
22 24 QObject. Using SuperQObject instead of QObject is highly recommended. See
23 25 QtKernelManager for an example.
24 26 """
25 pass
27 def __new__(mcls, name, bases, classdict):
28 # FIXME: this duplicates the code from MetaHasTraits.
29 # I don't think a super() call will help me here.
30 for k,v in classdict.iteritems():
31 if isinstance(v, TraitType):
32 v.name = k
33 elif inspect.isclass(v):
34 if issubclass(v, TraitType):
35 vinst = v()
36 vinst.name = k
37 classdict[k] = vinst
38 cls = MetaQObject.__new__(mcls, name, bases, classdict)
39 return cls
40
41 def __init__(mcls, name, bases, classdict):
42 # Note: super() did not work, so we explicitly call these.
43 MetaQObject.__init__(mcls, name, bases, classdict)
44 MetaHasTraits.__init__(mcls, name, bases, classdict)
26 45
27 46 #-----------------------------------------------------------------------------
28 47 # Classes
29 48 #-----------------------------------------------------------------------------
30 49
31 50 class SuperQObject(QtCore.QObject):
32 51 """ Permits the use of super() in class hierarchies that contain QObject.
33 52
34 53 Unlike QObject, SuperQObject does not accept a QObject parent. If it did,
35 54 super could not be emulated properly (all other classes in the heierarchy
36 55 would have to accept the parent argument--they don't, of course, because
37 56 they don't inherit QObject.)
38 57
39 58 This class is primarily useful for attaching signals to existing non-Qt
40 59 classes. See QtKernelManager for an example.
41 60 """
42 61
43 62 def __new__(cls, *args, **kw):
44 63 # We initialize QObject as early as possible. Without this, Qt complains
45 64 # if SuperQObject is not the first class in the super class list.
46 65 inst = QtCore.QObject.__new__(cls)
47 66 QtCore.QObject.__init__(inst)
48 67 return inst
49 68
50 69 def __init__(self, *args, **kw):
51 70 # Emulate super by calling the next method in the MRO, if there is one.
52 71 mro = self.__class__.mro()
53 72 for qt_class in QtCore.QObject.mro():
54 73 mro.remove(qt_class)
55 74 next_index = mro.index(SuperQObject) + 1
56 75 if next_index < len(mro):
57 76 mro[next_index].__init__(self, *args, **kw)
58 77
59 78 #-----------------------------------------------------------------------------
60 79 # Functions
61 80 #-----------------------------------------------------------------------------
62 81
63 82 def get_font(family, fallback=None):
64 83 """Return a font of the requested family, using fallback as alternative.
65 84
66 85 If a fallback is provided, it is used in case the requested family isn't
67 86 found. If no fallback is given, no alternative is chosen and Qt's internal
68 87 algorithms may automatically choose a fallback font.
69 88
70 89 Parameters
71 90 ----------
72 91 family : str
73 92 A font name.
74 93 fallback : str
75 94 A font name.
76 95
77 96 Returns
78 97 -------
79 98 font : QFont object
80 99 """
81 100 font = QtGui.QFont(family)
82 101 # Check whether we got what we wanted using QFontInfo, since exactMatch()
83 102 # is overly strict and returns false in too many cases.
84 103 font_info = QtGui.QFontInfo(font)
85 104 if fallback is not None and font_info.family() != family:
86 105 font = QtGui.QFont(fallback)
87 106 return font
General Comments 0
You need to be logged in to leave comments. Login now