5 from string
import Template
7 PYTHONQT_WRAPPER_WITH_PARENT = Template(
"""
8 //-----------------------------------------------------------------------------
9 class PythonQtWrapper_${className} : public QObject
14 ${className}* new_${className}(${parentClassName}* parent = 0)
16 return new ${className}(parent);
18 void delete_${className}(${className}* obj) { delete obj; }
22 PYTHONQT_WRAPPER_WITHOUT_PARENT = Template(
"""
23 //-----------------------------------------------------------------------------
24 class PythonQtWrapper_${className} : public QObject
29 ${className}* new_${className}()
31 return new ${className}();
33 void delete_${className}(${className}* obj) { delete obj; }
41 except OSError
as exc:
42 if exc.errno == errno.EEXIST
and os.path.isdir(path):
48 print(
"target: %s" % target)
49 print(
"namespace: %s" % namespace)
50 print(
"output_dir: %s" % output_dir)
51 print(
"input_files: %s" % input_files)
58 namespace = namespace.replace(
'.',
'_')
60 for input_file
in input_files:
61 filename = os.path.basename(input_file)
63 print(
"Wrapping %s" % filename)
66 filename_we = os.path.splitext(filename)[0]
69 className = filename_we
71 print(
"\tclassName:%s" % className)
74 parentClassName =
None
77 with open(input_file)
as f:
81 if 'Q_OBJECT' not in content:
83 print(
"\tskipping - No Q_OBJECT macro")
91 regex =
r"[^~]%s[\s\n]*\([\s\n]*((QObject|QWidget)[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\)|\)))" % className
92 res = re.search(regex, content, re.MULTILINE)
95 print(
"\tskipping - Missing expected constructor signature")
100 regex =
r"virtual[\w\n\s\*\(\)]+\=[\s\n]*(0|NULL)[\s\n]*\x3b"
101 res = re.search(regex, content, re.MULTILINE)
104 print(
"skipping - Contains a virtual pure method")
107 if parentClassName
is None:
109 regex =
r"[^~]%s[\s\n]*\([\s\n]*\)" % className
110 res = re.search(regex, content, re.MULTILINE)
115 print(
"\tconstructor of the form: %s()" % className)
117 if parentClassName
is None:
119 regex =
r"%s[\s\n]*\([\s\n]*QObject[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\))" % className
120 res = re.search(regex, content, re.MULTILINE)
122 parentClassName =
"QObject"
124 print(
"\tconstructor of the form: %s(QObject * parent ... )" % className)
126 if parentClassName
is None:
128 regex =
r"%s[\s\n]*\([\s\n]*QWidget[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\))" % className
129 res = re.search(regex, content, re.MULTILINE)
131 parentClassName =
"QWidget"
133 print(
"\tconstructor of the form: %s(QWidget * parent ... )" % className)
135 if parentClassName
is not None:
136 includes.append(
'#include "%s.h"' % filename_we)
139 if parentClassName ==
"QObject" or parentClassName ==
"QWidget":
140 pythonqtWrappers.append(
141 PYTHONQT_WRAPPER_WITH_PARENT.substitute(className = className, parentClassName = parentClassName))
143 elif parentClassName ==
"":
144 pythonqtWrappers.append(PYTHONQT_WRAPPER_WITHOUT_PARENT.substitute(className = className))
147 raise Exception(
"Problem wrapping %s" % input_file)
150 registerclasses.append(
152 PythonQt::self()->registerClass(
153 &${className}::staticMetaObject, "${target}",
154 PythonQtCreateObject<PythonQtWrapper_${className}>);
155 """).substitute(className = className, target = target))
157 output_header = output_dir +
"/" + namespace +
"_" + target +
".h"
159 print(
"output_header: %s" % output_header)
161 with open(output_header,
"w")
as f:
165 // File auto-generated by ctkWrapPythonQt.py
168 #ifndef __${namespace}_${target}_h
169 #define __${namespace}_${target}_h
175 """).substitute(namespace = namespace, target = target, includes =
'\n'.join(includes), pythonqtWrappers =
'\n'.join(pythonqtWrappers)))
177 output_cpp = output_dir +
"/" + namespace +
"_" + target +
"_init.cpp"
179 print(
"output_cpp: %s" % output_cpp)
180 with open(output_cpp ,
"w")
as f:
185 // File auto-generated by ctkWrapPythonQt.py
188 #include <PythonQt.h>
189 // XXX Avoid warning: "HAVE_XXXX" redefined
195 #undef HAVE_SYS_UTIME_H
198 #undef HAVE_LONG_LONG
200 #include "${namespace}_${target}.h"
202 void PythonQt_init_${namespace}_${target}(PyObject* module)
207 """).substitute(namespace = namespace, target = target, registerclasses =
'\n'.join(registerclasses)))
209 if __name__ ==
'__main__':
210 from optparse
import OptionParser
211 usage =
"usage: %prog [options] <output_file> <input_file> [<input_file1> [...]]"
212 parser = OptionParser(usage=usage)
213 parser.add_option(
"-t",
"--target",
214 dest=
"target", action=
"store", type=
"string",
215 help=
"Name of the associated library")
216 parser.add_option(
"-n",
"--namespace",
217 dest=
"namespace", action=
"store", type=
"string",
218 help=
"Wrapping namespace")
219 parser.add_option(
"--output-dir",
220 dest=
"output_dir", action=
"store", type=
"string",
221 help=
"Output directory")
222 parser.add_option(
"-v",
"--verbose",
223 dest=
"verbose", action=
"store_true",
224 help=
"Print verbose information")
225 parser.add_option(
"--extra-verbose",
226 dest=
"extra_verbose", action=
"store_true",
227 help=
"Print extra verbose information")
229 (options, args) = parser.parse_args()
234 if options.extra_verbose:
235 options.verbose =
True
237 ctk_wrap_pythonqt(options.target, options.namespace, options.output_dir, args, options.extra_verbose)
240 print(
"Wrapped %d files" % len(args))
def ctk_wrap_pythonqt(target, namespace, output_dir, input_files, extra_verbose)