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