|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2011 - 2018 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module to get sys.path of an external interpreter. |
|
8 """ |
|
9 |
|
10 from __future__ import print_function |
|
11 try: |
|
12 bytes = unicode # __IGNORE_EXCEPTION__ |
|
13 except NameError: |
|
14 pass |
|
15 |
|
16 import sys |
|
17 import json |
|
18 import xml.etree.ElementTree |
|
19 |
|
20 try: |
|
21 from PyQt5.QtCore import qVersion, QMetaMethod, QByteArray |
|
22 from PyQt5.QtWidgets import QAction, QWidget, QApplication |
|
23 from PyQt5 import uic |
|
24 |
|
25 pyqtType = 5 |
|
26 except ImportError: |
|
27 try: |
|
28 # try a potential PyQt4 installation |
|
29 from PyQt4.QtCore import qVersion, QMetaMethod, QByteArray |
|
30 from PyQt4.QtGui import QAction, QWidget, QApplication |
|
31 from PyQt4 import uic |
|
32 |
|
33 pyqtType = 4 |
|
34 except ImportError: |
|
35 print("Neither PyQt5 nor PyQt4 found.") |
|
36 sys.exit(1) |
|
37 |
|
38 |
|
39 def objectName(formFile, projectPath): |
|
40 """ |
|
41 Function to get the object name of a form. |
|
42 |
|
43 @param formFile file name of the form |
|
44 @type str |
|
45 @param projectPath directory name of the project |
|
46 @type str |
|
47 """ |
|
48 app = QApplication([]) # __IGNORE_WARNING__ |
|
49 try: |
|
50 dlg = uic.loadUi(formFile, package=projectPath) |
|
51 print(dlg.objectName()) |
|
52 sys.exit(0) |
|
53 except (AttributeError, ImportError, |
|
54 xml.etree.ElementTree.ParseError) as err: |
|
55 print(str(err)) |
|
56 sys.exit(1) |
|
57 |
|
58 |
|
59 def className(formFile, projectPath): |
|
60 """ |
|
61 Function to get the class name of a form. |
|
62 |
|
63 @param formFile file name of the form |
|
64 @type str |
|
65 @param projectPath directory name of the project |
|
66 @type str |
|
67 """ |
|
68 app = QApplication([]) # __IGNORE_WARNING__ |
|
69 try: |
|
70 dlg = uic.loadUi(formFile, package=projectPath) |
|
71 print(dlg.metaObject().className()) |
|
72 sys.exit(0) |
|
73 except (AttributeError, ImportError, |
|
74 xml.etree.ElementTree.ParseError) as err: |
|
75 print(str(err)) |
|
76 sys.exit(1) |
|
77 |
|
78 |
|
79 def __mapType(type_): |
|
80 """ |
|
81 Private function to map a type as reported by Qt's meta object to the |
|
82 correct Python type. |
|
83 |
|
84 @param type_ type as reported by Qt |
|
85 @type QByteArray or bytes |
|
86 @return mapped Python type |
|
87 @rtype str |
|
88 """ |
|
89 mapped = bytes(type_).decode() |
|
90 |
|
91 # I. always check for * |
|
92 mapped = mapped.replace("*", "") |
|
93 |
|
94 if pyqtType != 4: |
|
95 # 1. check for const |
|
96 mapped = mapped.replace("const ", "") |
|
97 |
|
98 # 2. replace QString and QStringList |
|
99 mapped = mapped.replace("QStringList", "list")\ |
|
100 .replace("QString", "str") |
|
101 |
|
102 # 3. replace double by float |
|
103 mapped = mapped.replace("double", "float") |
|
104 |
|
105 return mapped |
|
106 |
|
107 |
|
108 def signatures(formFile, projectPath): |
|
109 """ |
|
110 Function to get the signatures of form elements. |
|
111 |
|
112 @param formFile file name of the form |
|
113 @type str |
|
114 @param projectPath directory name of the project |
|
115 @type str |
|
116 """ |
|
117 objectsList = [] |
|
118 |
|
119 app = QApplication([]) # __IGNORE_WARNING__ |
|
120 try: |
|
121 dlg = uic.loadUi(formFile, package=projectPath) |
|
122 objects = dlg.findChildren(QWidget) + dlg.findChildren(QAction) |
|
123 for obj in objects: |
|
124 name = obj.objectName() |
|
125 if not name or name.startswith("qt_"): |
|
126 # ignore un-named or internal objects |
|
127 continue |
|
128 |
|
129 metaObject = obj.metaObject() |
|
130 objectDict = { |
|
131 "name": name, |
|
132 "class_name": metaObject.className(), |
|
133 "methods": [], |
|
134 } |
|
135 |
|
136 for index in range(metaObject.methodCount()): |
|
137 metaMethod = metaObject.method(index) |
|
138 if metaMethod.methodType() == QMetaMethod.Signal: |
|
139 signatureDict = { |
|
140 "methods": [] |
|
141 } |
|
142 if qVersion().startswith("5."): |
|
143 signatureDict["signature"] = "on_{0}_{1}".format( |
|
144 name, |
|
145 bytes(metaMethod.methodSignature()).decode() |
|
146 ) |
|
147 else: |
|
148 signatureDict["signature"] = "on_{0}_{1}".format( |
|
149 name, |
|
150 metaMethod.signature() |
|
151 ) |
|
152 |
|
153 if qVersion().startswith("5."): |
|
154 signatureDict["methods"].append("on_{0}_{1}".format( |
|
155 name, |
|
156 bytes(metaMethod.methodSignature()) |
|
157 .decode().split("(")[0] |
|
158 )) |
|
159 else: |
|
160 signatureDict["methods"].append("on_{0}_{1}".format( |
|
161 name, |
|
162 metaMethod.signature().split("(")[0] |
|
163 )) |
|
164 signatureDict["methods"].append("{0}({1})".format( |
|
165 signatureDict["methods"][-1], |
|
166 ", ".join([ |
|
167 __mapType(t) |
|
168 for t in metaMethod.parameterTypes() |
|
169 ]) |
|
170 )) |
|
171 |
|
172 returnType = __mapType( |
|
173 metaMethod.typeName().encode()) |
|
174 if returnType == 'void': |
|
175 returnType = "" |
|
176 signatureDict["return_type"] = returnType |
|
177 parameterTypesList = [ |
|
178 __mapType(t) |
|
179 for t in metaMethod.parameterTypes() |
|
180 ] |
|
181 signatureDict["parameter_types"] = parameterTypesList |
|
182 pyqtSignature = ", ".join(parameterTypesList) |
|
183 signatureDict["pyqt_signature"] = pyqtSignature |
|
184 |
|
185 parameterNames = metaMethod.parameterNames() |
|
186 if parameterNames: |
|
187 for index in range(len(parameterNames)): |
|
188 if not parameterNames[index]: |
|
189 parameterNames[index] = \ |
|
190 QByteArray("p{0:d}".format(index) |
|
191 .encode("utf-8")) |
|
192 parameterNamesList = [bytes(n).decode() |
|
193 for n in parameterNames] |
|
194 signatureDict["parameter_names"] = parameterNamesList |
|
195 methNamesSig = ", ".join(parameterNamesList) |
|
196 |
|
197 if methNamesSig: |
|
198 if qVersion().startswith("5."): |
|
199 pythonSignature = \ |
|
200 "on_{0}_{1}(self, {2})".format( |
|
201 name, |
|
202 bytes(metaMethod.methodSignature()) |
|
203 .decode().split("(")[0], |
|
204 methNamesSig) |
|
205 else: |
|
206 pythonSignature = \ |
|
207 "on_{0}_{1}(self, {2})".format( |
|
208 name, |
|
209 metaMethod.signature().split("(")[0], |
|
210 methNamesSig) |
|
211 else: |
|
212 if qVersion().startswith("5."): |
|
213 pythonSignature = "on_{0}_{1}(self)".format( |
|
214 name, |
|
215 bytes(metaMethod.methodSignature()) |
|
216 .decode().split("(")[0]) |
|
217 else: |
|
218 pythonSignature = "on_{0}_{1}(self)".format( |
|
219 name, |
|
220 metaMethod.signature().split("(")[0]) |
|
221 signatureDict["python_signature"] = pythonSignature |
|
222 |
|
223 objectDict["methods"].append(signatureDict) |
|
224 |
|
225 objectsList.append(objectDict) |
|
226 |
|
227 print(json.dumps(objectsList)) |
|
228 sys.exit(0) |
|
229 except (AttributeError, ImportError, |
|
230 xml.etree.ElementTree.ParseError) as err: |
|
231 print(str(err)) |
|
232 sys.exit(1) |
|
233 |
|
234 |
|
235 if __name__ == "__main__": |
|
236 if len(sys.argv) != 4: |
|
237 print("Wrong number of arguments.") |
|
238 sys.exit(1) |
|
239 |
|
240 if sys.argv[1] == "object_name": |
|
241 objectName(sys.argv[2], sys.argv[3]) |
|
242 elif sys.argv[1] == "class_name": |
|
243 className(sys.argv[2], sys.argv[3]) |
|
244 elif sys.argv[1] == "signatures": |
|
245 signatures(sys.argv[2], sys.argv[3]) |
|
246 else: |
|
247 print("Unknow operation given.") |
|
248 sys.exit(1) |
|
249 |
|
250 # |
|
251 # eflag: noqa = M701, M801 |