src/eric7/Project/UicLoadUi5.py

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

eric ide

mercurial