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