| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 | 
							
- import errno
 
- import os
 
- import re
 
- from string import Template
 
- PYTHONQT_WRAPPER_WITH_PARENT = Template("""
 
- //-----------------------------------------------------------------------------
 
- class PythonQtWrapper_${className} : public QObject
 
- {
 
- Q_OBJECT
 
- public:
 
- public Q_SLOTS:
 
-   ${className}* new_${className}(${parentClassName}*  parent = 0)
 
-     {
 
-     return new ${className}(parent);
 
-     }
 
-   void delete_${className}(${className}* obj) { delete obj; }
 
- };
 
- """)
 
- PYTHONQT_WRAPPER_WITHOUT_PARENT = Template("""
 
- //-----------------------------------------------------------------------------
 
- class PythonQtWrapper_${className} : public QObject
 
- {
 
- Q_OBJECT
 
- public:
 
- public Q_SLOTS:
 
-   ${className}* new_${className}()
 
-     {
 
-     return new ${className}();
 
-     }
 
-   void delete_${className}(${className}* obj) { delete obj; }
 
- };
 
- """)
 
- def _mkdir_p(path):
 
-     """See """
 
-     try:
 
-         os.makedirs(path)
 
-     except OSError as exc:
 
-         if exc.errno == errno.EEXIST and os.path.isdir(path):
 
-             pass
 
-         else: raise
 
- def ctk_wrap_pythonqt(target, namespace, output_dir, input_files, extra_verbose):
 
-     if extra_verbose:
 
-         print("target: %s" % target)
 
-         print("namespace: %s" % namespace)
 
-         print("output_dir: %s" % output_dir)
 
-         print("input_files: %s" % input_files)
 
-     
 
-     _mkdir_p(output_dir)
 
-     
 
-     includes = []
 
-     pythonqtWrappers = []
 
-     registerclasses = []
 
-     namespace = namespace.replace('.', '_')
 
-     
 
-     for input_file in input_files:
 
-         filename = os.path.basename(input_file)
 
-         if extra_verbose:
 
-             print("Wrapping %s" % filename)
 
-        
 
-         # what is the filename without the extension
 
-         filename_we = os.path.splitext(filename)[0]
 
-         # Extract classname - NOTE: We assume the filename matches the associated class
 
-         className = filename_we
 
-         if extra_verbose:
 
-             print("\tclassName:%s" % className)
 
-         # Extract parent classname
 
-         parentClassName = None
 
-         # Read input files
 
-         with open(input_file) as f:
 
-             content = f.read()
 
-             
 
-             # Skip wrapping if file do NOT contain Q_OBJECT
 
-             if 'Q_OBJECT' not in content:
 
-                 if extra_verbose:
 
-                     print("\tskipping - No Q_OBJECT macro")
 
-                 continue
 
-             # Skip wrapping if constructor doesn't match:
 
-             #    my_class()
 
-             #    my_class(QObject* newParent ...)
 
-             #    my_class(QWidget* newParent ...)
 
-             # Constructor with either QWidget or QObject as first parameter
 
-             regex = r"[^~]%s[\s\n]*\([\s\n]*((QObject|QWidget)[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\)|\)))" % className
 
-             res = re.search(regex, content, re.MULTILINE)
 
-             if res is None:
 
-                 if extra_verbose:
 
-                     print("\tskipping - Missing expected constructor signature")
 
-                 continue
 
-      
 
-             # Skip wrapping if object has a virtual pure method
 
-             # "x3b" is the unicode for semicolon
 
-             regex = r"virtual[\w\n\s\*\(\)]+\=[\s\n]*(0|NULL)[\s\n]*\x3b"
 
-             res = re.search(regex, content, re.MULTILINE)
 
-             if res is not None:
 
-                 if extra_verbose:
 
-                     print("skipping - Contains a virtual pure method")
 
-                 continue
 
-             if parentClassName is None:
 
-                 # Does constructor signature is of the form: myclass()
 
-                 regex = r"[^~]%s[\s\n]*\([\s\n]*\)" % className
 
-                 res = re.search(regex, content, re.MULTILINE)
 
-            
 
-                 if res is not None:
 
-                     parentClassName = ""
 
-                     if extra_verbose:
 
-                         print("\tconstructor of the form: %s()" % className)
 
-             if parentClassName is None:
 
-                 # Does constructor signature is of the form: myclass(QObject * parent ...)
 
-                 regex = r"%s[\s\n]*\([\s\n]*QObject[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\))" % className
 
-                 res = re.search(regex, content, re.MULTILINE)
 
-                 if res is not None:
 
-                     parentClassName = "QObject"
 
-                     if extra_verbose:
 
-                         print("\tconstructor of the form: %s(QObject * parent ... )" % className)
 
-             if parentClassName is None:
 
-                 # Does constructor signature is of the form: myclass(QWidget * parent ...)
 
-                 regex = r"%s[\s\n]*\([\s\n]*QWidget[\s\n]*\*[\s\n]*\w+[\s\n]*(\=[\s\n]*(0|NULL)|,.*\=.*\)|\))" % className
 
-                 res = re.search(regex, content, re.MULTILINE)
 
-                 if res is not None:
 
-                     parentClassName = "QWidget"
 
-                     if extra_verbose:
 
-                         print("\tconstructor of the form: %s(QWidget * parent ... )" % className)
 
-         if parentClassName is not None:
 
-             includes.append('#include "%s.h"' % filename_we)
 
-         # Generate PythonQtWrapper class
 
-         if parentClassName == "QObject" or parentClassName == "QWidget":
 
-             pythonqtWrappers.append(
 
-                 PYTHONQT_WRAPPER_WITH_PARENT.substitute(className = className, parentClassName = parentClassName))
 
-             
 
-         elif parentClassName == "":
 
-             pythonqtWrappers.append(PYTHONQT_WRAPPER_WITHOUT_PARENT.substitute(className = className))
 
-         else: # Case parentClassName is None
 
-             raise Exception("Problem wrapping %s" % input_file)
 
-         
 
-         # Generate code allowing to register the class metaobject and its associated "light" wrapper
 
-         registerclasses.append(
 
-         Template("""
 
-   PythonQt::self()->registerClass(
 
-   &${className}::staticMetaObject, "${target}",
 
-   PythonQtCreateObject<PythonQtWrapper_${className}>);
 
-   """).substitute(className = className, target = target))
 
-     output_header = output_dir + "/" + namespace + "_" + target + ".h"
 
-     if extra_verbose:
 
-         print("output_header: %s" % output_header)
 
-     # Write master include file
 
-     with open(output_header, "w") as f:
 
-         f.write(Template(
 
- """
 
- //
 
- // File auto-generated by ctkWrapPythonQt.py
 
- //
 
- #ifndef __${namespace}_${target}_h
 
- #define __${namespace}_${target}_h
 
- #include <QWidget>
 
- ${includes}
 
- ${pythonqtWrappers}
 
- #endif
 
- """).substitute(namespace = namespace, target = target, includes = '\n'.join(includes), pythonqtWrappers = '\n'.join(pythonqtWrappers)))
 
-     output_cpp = output_dir + "/" + namespace + "_" + target + "_init.cpp"
 
-     if extra_verbose:
 
-         print("output_cpp: %s" % output_cpp)
 
-     with open(output_cpp , "w") as f:
 
-         # Write wrapper header
 
-         f.write(Template(
 
- """
 
- //
 
- // File auto-generated by ctkWrapPythonQt.py
 
- //
 
- #include <PythonQt.h>
 
- #include "${namespace}_${target}.h"
 
- void PythonQt_init_${namespace}_${target}(PyObject* module)
 
- {
 
-   Q_UNUSED(module);
 
-   ${registerclasses}
 
- }
 
- """).substitute(namespace = namespace, target = target, registerclasses = '\n'.join(registerclasses)))
 
- if __name__ == '__main__':
 
-     from optparse import OptionParser
 
-     usage = "usage: %prog [options] <output_file> <input_file> [<input_file1> [...]]"
 
-     parser = OptionParser(usage=usage)
 
-     parser.add_option("-t", "--target",
 
-                       dest="target", action="store", type="string",
 
-                       help="Name of the associated library")
 
-     parser.add_option("-n", "--namespace",
 
-                       dest="namespace", action="store", type="string",
 
-                       help="Wrapping namespace")
 
-     parser.add_option("--output-dir",
 
-                       dest="output_dir", action="store", type="string",
 
-                       help="Output directory")
 
-     parser.add_option("-v", "--verbose",
 
-                       dest="verbose", action="store_true",
 
-                       help="Print verbose information")
 
-     parser.add_option("--extra-verbose",
 
-                       dest="extra_verbose", action="store_true",
 
-                       help="Print extra verbose information")
 
-     (options, args) = parser.parse_args()
 
-     #if len(args) < 2:
 
-     #    parser.error("arguments '%s' are required !" % '<output_file> <input_file>')
 
-     if options.extra_verbose:
 
-         options.verbose = True
 
-     ctk_wrap_pythonqt(options.target, options.namespace, options.output_dir, args, options.extra_verbose)
 
-       
 
-     if options.verbose:
 
-         print("Wrapped %d files" % len(args))
 
 
  |