Commits

Henning Schröder  committed 94876c6

refactoring

  • Participants
  • Parent commits 55e26c9

Comments (0)

Files changed (10)

File console.py

-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-import sys
-from PyQt4.QtCore import Qt, QRegExp
-from PyQt4.QtGui import (
-   QDialog, QPlainTextEdit, QVBoxLayout, QSplitter, QPushButton, QTextCursor,
-   QSyntaxHighlighter, QTextCharFormat, QColor)
-
-
-class DefaultColorScheme:
-    syntax_keyword="#808000" # darkYellow
-    syntax_builtin="brown" 
-    syntax_magic="magenta"
-    syntax_self="darkMagenta"
-    syntax_comment="darkGray"
-    syntax_string="darkGreen"
-    syntax_number="darkBlue"
-scheme = DefaultColorScheme
-
-example = """
-for i in range(3):
-    print i, 'Hello, world!'
-"""
-
-class PythonHighlighter(QSyntaxHighlighter):
-
-    keywords = (
-        "and",       "del",       "for",       "is",        "raise",
-        "assert",    "elif",      "from",      "lambda",    "return",
-        "break",     "else",      "global",    "not",       "try",
-        "class",     "except",    "if",        "or",        "while",
-        "continue",  "exec",      "import",    "pass",      "yield",
-        "def",       "finally",   "in",        "print",     "with"
-        )
-    builtins = ('ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 
-    'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 
-    'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 
-    'LookupError', 'MemoryError', 'NameError', 'None', 
-    'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 
-    'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 
-    'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 
-    'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__debug__', '__doc__', '__import__', '__name__', '__package__', 
-    'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 
-    'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 
-    'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 
-    'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 
-    'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'next', 
-    'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 
-    'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 
-    'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip') 
-    
-
-    def __init__(self, edit):
-        self.textedit = edit
-        document = edit.document()
-        QSyntaxHighlighter.__init__(self, document)
-
-        base_format = QTextCharFormat()
-        base_format.setFont(edit.font())
-        self.base_format = base_format
-        self.document = document
-        
-        self.updateHighlighter(base_format.font())
-
-
-    def highlightBlock(self, text):
-        self.setCurrentBlockState(0)
-        
-        if text.trimmed().isEmpty():
-            self.setFormat(0, len(text), self.empty_format)
-            return
-        
-        self.setFormat(0, len(text), self.base_format)
-        
-        startIndex = 0
-        if self.previousBlockState() != 1:
-            startIndex = self.multiLineStringBegin.indexIn(text)
-        
-        if startIndex > -1:
-            self.highlightRules(text, 0, startIndex)
-        else:
-            self.highlightRules(text, 0, len(text))
-        
-        while startIndex >= 0:
-            endIndex = self.multiLineStringEnd.indexIn(text, 
-                  startIndex + len(self.multiLineStringBegin.pattern()))
-            if endIndex == -1:
-                self.setCurrentBlockState(1)
-                commentLength = text.length() - startIndex
-            else:
-                commentLength = endIndex - startIndex + \
-                                self.multiLineStringEnd.matchedLength()
-                self.highlightRules(text, endIndex, len(text))
-            
-            self.setFormat(startIndex, commentLength, self.multiLineStringFormat)
-            startIndex = self.multiLineStringBegin.indexIn(text, 
-                                           startIndex + commentLength)
-    
-    
-    def highlightRules(self, text, start, finish):
-        for expression, format in self.rules:
-            index = expression.indexIn(text, start)
-            while index >= start and index < finish:
-                length = expression.matchedLength()
-                self.setFormat(index, min(length, finish - index), format)
-                index = expression.indexIn(text, index + length)
-    
-
-    def updateFonts(self, font):    
-        self.base_format.setFont(font)
-        self.empty_format = QTextCharFormat(self.base_format)
-        #self.empty_format.setFontPointSize(font.pointSize()/4.0)
-        
-        self.keywordFormat = QTextCharFormat(self.base_format)
-        self.keywordFormat.setForeground(QColor(scheme.syntax_keyword))
-        #self.keywordFormat.setFontWeight(QFont.Bold)
-        self.builtinFormat = QTextCharFormat(self.base_format)
-        self.builtinFormat.setForeground(QColor(scheme.syntax_builtin))
-        self.magicFormat = QTextCharFormat(self.base_format)
-        self.magicFormat.setForeground(QColor(scheme.syntax_magic))
-        #self.qtFormat = QTextCharFormat(self.base_format)
-        #self.qtFormat.setForeground(QColor(scheme.syntax_qt))
-        ##self.qtFormat.setFontWeight(QFont.Bold)
-        self.selfFormat = QTextCharFormat(self.base_format)
-        self.selfFormat.setForeground(QColor(scheme.syntax_self))
-        #self.selfFormat.setFontItalic(True)
-        self.singleLineCommentFormat = QTextCharFormat(self.base_format)
-        self.singleLineCommentFormat.setForeground(QColor(scheme.syntax_comment))
-        self.singleLineCommentFormat.setFontItalic(True)
-        self.multiLineStringFormat = QTextCharFormat(self.base_format)
-        self.multiLineStringFormat.setForeground(QColor(scheme.syntax_string))
-        #self.multiLineStringFormat.setBackground(QBrush(Qt.green))
-        self.quotationFormat1 = QTextCharFormat(self.base_format)
-        self.quotationFormat1.setForeground(QColor(scheme.syntax_string))
-        self.quotationFormat2 = QTextCharFormat(self.base_format)
-        self.quotationFormat2.setForeground(QColor(scheme.syntax_string))
-        self.numFormat = QTextCharFormat(self.base_format)
-        self.numFormat.setForeground(QColor(scheme.syntax_number))
-
-
-    def updateRules(self):
-        self.rules = []
-        self.rules += map(lambda s: (QRegExp(r"\b"+s+r"\b"),
-                          self.keywordFormat), self.keywords)
-        self.rules += map(lambda s: (QRegExp(r"\b"+s+r"\b"),
-                          self.builtinFormat), self.builtins)
-
-        self.rules.append((QRegExp(r"\b__[a-z]+__\b"), self.magicFormat))
-        self.rules.append((QRegExp(r"\bself\b"), self.selfFormat))
-        self.rules.append((QRegExp(r"\b\d+(\.\d*)?\b"), self.numFormat))
-        #self.rules.append((QRegExp(r"\bQ([A-Z][a-z]*)+\b"), self.qtFormat))
-        self.rules.append((QRegExp(r"#[^\n]*"), self.singleLineCommentFormat))
-        self.multiLineStringBegin = QRegExp(r'\"\"\"')
-        self.multiLineStringEnd = QRegExp(r'\"\"\"')
-        self.rules.append((QRegExp(r'\"[^\n]*\"'), self.quotationFormat1))
-        self.rules.append((QRegExp(r"'[^\n]*'"), self.quotationFormat2))
-    
-
-    def updateHighlighter(self, font):    
-        self.updateFonts(font)
-        self.updateRules()
-        self.setDocument(self.document)
-
-
-
-
-class EditorWidget(QPlainTextEdit):
-
-    
-    def __init__(self, parent):
-        super(EditorWidget, self).__init__(parent)
-        self.highlighter = PythonHighlighter(self)
-
-
-class OutputWidget(QPlainTextEdit):
-
-    
-    def __init__(self, parent):
-        super(OutputWidget, self).__init__(parent)
-        self.setReadOnly(True)
-        sys.stdout = self
-        sys.stderr = self
-        self.buf = u""
-        self.startTimer(500)
-
-        
-    def write(self, s):
-        sys.__stdout__.write(s)
-        self.buf += unicode(s)
-
-        
-    def writeline(self, s):
-        self.write(u"%s\n" % s)
-
-        
-    def timerEvent(self, event):
-        self.flush()
-
-        
-    def flush(self):
-        if self.buf:
-            if not self.window().isVisible():
-                self.window().show()
-            self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
-            self.textCursor().insertText(self.buf)          
-            self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
-            self.ensureCursorVisible()
-            self.buf = ""
-
-
-    
-class Console(QDialog):
-
-
-    def __init__(self, namespace=None):
-        QDialog.__init__(self)
-        if namespace is None:
-            namespace = {}
-        self.namespace = namespace
-        self.vblayout = QVBoxLayout(self)
-        self.splitter = QSplitter(Qt.Vertical, self)
-        self.layout().addWidget(self.splitter)
-        self.edit = EditorWidget(self.splitter)
-        self.edit.setPlainText(example)
-        self.output = OutputWidget(self.splitter)       
-        self.runButton = QPushButton(self, text="&Run")
-        self.runButton.clicked.connect(self.run)
-        self.layout().addWidget(self.runButton)
-        self.edit.setFocus()
-        self.resize(800, 600)
-        
-    def run(self):
-        code = unicode(self.edit.toPlainText())
-        try:
-            exec code in self.namespace
-        except Exception, e:
-            print "\n", "-"*40
-            print e
-            import traceback
-            traceback.print_exc()
-    
-        
-
-        
-
-        
-if __name__ == "__main__":
-    import sys
-    from PyQt4.QtGui import QApplication
-    app = QApplication(sys.argv)
-    win = Console()
-    win.show()
-    app.exec_()
-    

File embeddedpyqt.py

-# -*- coding: utf-8 -*-
-import sys
-import os
-
-import sip
-from PyQt4.QtGui import qApp
-from PyQt4.QtCore import QMetaObject
-
-path = os.path.dirname(os.path.abspath(__file__))
-if path not in sys.path:
-	sys.path.insert(0, path)
-
-from console import Console
-from pyqtproxy import class_from_metaobject, wrap_instance
-
-
-
-embpyqt = wrap_instance(qApp.property("embedded_pyqt").toPyObject())
-
-
-def class_by_name(name):
-	ptr = embpyqt.metaObjectByName(name)
-	mo = sip.wrapinstance(int(ptr), QMetaObject)
-	return class_from_metaobject(mo)
-
-
-
-namespace = {}
-embpyqt_console = wrap_instance(Console(namespace))
-
-
-namespace.update(
-   embpyqt_console=embpyqt_console, 
-   embpyqt=embpyqt)
-
-
-for class_name in embpyqt.availableClasses():
-	cls = class_by_name(class_name)
-	class_name = str(class_name)
-	namespace[class_name] = cls
-
-
-for k, v in namespace.items():
-	globals()[k] = v
-
-__all__ = namespace.keys()
-
-print __file__, "loaded with", __all__

File embpyqt/python/embeddedpyqt/__init__.py

+# -*- coding: utf-8 -*-
+import sip
+from PyQt4.QtGui import qApp
+from PyQt4.QtCore import QMetaObject
+
+from embeddedpyqt.console import Console
+from embeddedpyqt.proxy import class_from_metaobject, wrap_instance
+
+
+
+embpyqt = wrap_instance(qApp.property("embedded_pyqt").toPyObject())
+
+
+def class_by_name(name):
+	ptr = embpyqt.metaObjectByName(name)
+	mo = sip.wrapinstance(int(ptr), QMetaObject)
+	return class_from_metaobject(mo)
+
+
+
+namespace = {}
+embpyqt_console = wrap_instance(Console(namespace))
+
+
+namespace.update(
+   embpyqt_console=embpyqt_console, 
+   embpyqt=embpyqt)
+
+
+for class_name in embpyqt.availableClasses():
+	cls = class_by_name(class_name)
+	class_name = str(class_name)
+	namespace[class_name] = cls
+
+
+for k, v in namespace.items():
+	globals()[k] = v
+
+__all__ = namespace.keys()
+
+print __file__, "loaded with", __all__

File embpyqt/python/embeddedpyqt/console.py

+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+import sys
+from PyQt4.QtCore import Qt, QRegExp
+from PyQt4.QtGui import (
+   QDialog, QPlainTextEdit, QVBoxLayout, QSplitter, QPushButton, QTextCursor,
+   QSyntaxHighlighter, QTextCharFormat, QColor)
+
+
+class DefaultColorScheme:
+    syntax_keyword="#808000" # darkYellow
+    syntax_builtin="brown" 
+    syntax_magic="magenta"
+    syntax_self="darkMagenta"
+    syntax_comment="darkGray"
+    syntax_string="darkGreen"
+    syntax_number="darkBlue"
+scheme = DefaultColorScheme
+
+example = """
+for i in range(3):
+    print i, 'Hello, world!'
+"""
+
+class PythonHighlighter(QSyntaxHighlighter):
+
+    keywords = (
+        "and",       "del",       "for",       "is",        "raise",
+        "assert",    "elif",      "from",      "lambda",    "return",
+        "break",     "else",      "global",    "not",       "try",
+        "class",     "except",    "if",        "or",        "while",
+        "continue",  "exec",      "import",    "pass",      "yield",
+        "def",       "finally",   "in",        "print",     "with"
+        )
+    builtins = ('ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BufferError', 'BytesWarning', 
+    'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 'FutureWarning', 
+    'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 
+    'LookupError', 'MemoryError', 'NameError', 'None', 
+    'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError', 'RuntimeWarning', 
+    'StandardError', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True', 'TypeError', 'UnboundLocalError', 
+    'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 
+    'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '__debug__', '__doc__', '__import__', '__name__', '__package__', 
+    'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 
+    'cmp', 'coerce', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 
+    'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float', 'format', 'frozenset', 'getattr', 
+    'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'intern', 'isinstance', 
+    'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min', 'next', 
+    'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'raw_input', 'reduce', 'reload', 
+    'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 
+    'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip') 
+    
+
+    def __init__(self, edit):
+        self.textedit = edit
+        document = edit.document()
+        QSyntaxHighlighter.__init__(self, document)
+
+        base_format = QTextCharFormat()
+        base_format.setFont(edit.font())
+        self.base_format = base_format
+        self.document = document
+        
+        self.updateHighlighter(base_format.font())
+
+
+    def highlightBlock(self, text):
+        self.setCurrentBlockState(0)
+        
+        if text.trimmed().isEmpty():
+            self.setFormat(0, len(text), self.empty_format)
+            return
+        
+        self.setFormat(0, len(text), self.base_format)
+        
+        startIndex = 0
+        if self.previousBlockState() != 1:
+            startIndex = self.multiLineStringBegin.indexIn(text)
+        
+        if startIndex > -1:
+            self.highlightRules(text, 0, startIndex)
+        else:
+            self.highlightRules(text, 0, len(text))
+        
+        while startIndex >= 0:
+            endIndex = self.multiLineStringEnd.indexIn(text, 
+                  startIndex + len(self.multiLineStringBegin.pattern()))
+            if endIndex == -1:
+                self.setCurrentBlockState(1)
+                commentLength = text.length() - startIndex
+            else:
+                commentLength = endIndex - startIndex + \
+                                self.multiLineStringEnd.matchedLength()
+                self.highlightRules(text, endIndex, len(text))
+            
+            self.setFormat(startIndex, commentLength, self.multiLineStringFormat)
+            startIndex = self.multiLineStringBegin.indexIn(text, 
+                                           startIndex + commentLength)
+    
+    
+    def highlightRules(self, text, start, finish):
+        for expression, format in self.rules:
+            index = expression.indexIn(text, start)
+            while index >= start and index < finish:
+                length = expression.matchedLength()
+                self.setFormat(index, min(length, finish - index), format)
+                index = expression.indexIn(text, index + length)
+    
+
+    def updateFonts(self, font):    
+        self.base_format.setFont(font)
+        self.empty_format = QTextCharFormat(self.base_format)
+        #self.empty_format.setFontPointSize(font.pointSize()/4.0)
+        
+        self.keywordFormat = QTextCharFormat(self.base_format)
+        self.keywordFormat.setForeground(QColor(scheme.syntax_keyword))
+        #self.keywordFormat.setFontWeight(QFont.Bold)
+        self.builtinFormat = QTextCharFormat(self.base_format)
+        self.builtinFormat.setForeground(QColor(scheme.syntax_builtin))
+        self.magicFormat = QTextCharFormat(self.base_format)
+        self.magicFormat.setForeground(QColor(scheme.syntax_magic))
+        #self.qtFormat = QTextCharFormat(self.base_format)
+        #self.qtFormat.setForeground(QColor(scheme.syntax_qt))
+        ##self.qtFormat.setFontWeight(QFont.Bold)
+        self.selfFormat = QTextCharFormat(self.base_format)
+        self.selfFormat.setForeground(QColor(scheme.syntax_self))
+        #self.selfFormat.setFontItalic(True)
+        self.singleLineCommentFormat = QTextCharFormat(self.base_format)
+        self.singleLineCommentFormat.setForeground(QColor(scheme.syntax_comment))
+        self.singleLineCommentFormat.setFontItalic(True)
+        self.multiLineStringFormat = QTextCharFormat(self.base_format)
+        self.multiLineStringFormat.setForeground(QColor(scheme.syntax_string))
+        #self.multiLineStringFormat.setBackground(QBrush(Qt.green))
+        self.quotationFormat1 = QTextCharFormat(self.base_format)
+        self.quotationFormat1.setForeground(QColor(scheme.syntax_string))
+        self.quotationFormat2 = QTextCharFormat(self.base_format)
+        self.quotationFormat2.setForeground(QColor(scheme.syntax_string))
+        self.numFormat = QTextCharFormat(self.base_format)
+        self.numFormat.setForeground(QColor(scheme.syntax_number))
+
+
+    def updateRules(self):
+        self.rules = []
+        self.rules += map(lambda s: (QRegExp(r"\b"+s+r"\b"),
+                          self.keywordFormat), self.keywords)
+        self.rules += map(lambda s: (QRegExp(r"\b"+s+r"\b"),
+                          self.builtinFormat), self.builtins)
+
+        self.rules.append((QRegExp(r"\b__[a-z]+__\b"), self.magicFormat))
+        self.rules.append((QRegExp(r"\bself\b"), self.selfFormat))
+        self.rules.append((QRegExp(r"\b\d+(\.\d*)?\b"), self.numFormat))
+        #self.rules.append((QRegExp(r"\bQ([A-Z][a-z]*)+\b"), self.qtFormat))
+        self.rules.append((QRegExp(r"#[^\n]*"), self.singleLineCommentFormat))
+        self.multiLineStringBegin = QRegExp(r'\"\"\"')
+        self.multiLineStringEnd = QRegExp(r'\"\"\"')
+        self.rules.append((QRegExp(r'\"[^\n]*\"'), self.quotationFormat1))
+        self.rules.append((QRegExp(r"'[^\n]*'"), self.quotationFormat2))
+    
+
+    def updateHighlighter(self, font):    
+        self.updateFonts(font)
+        self.updateRules()
+        self.setDocument(self.document)
+
+
+
+
+class EditorWidget(QPlainTextEdit):
+
+    
+    def __init__(self, parent):
+        super(EditorWidget, self).__init__(parent)
+        self.highlighter = PythonHighlighter(self)
+
+
+class OutputWidget(QPlainTextEdit):
+
+    
+    def __init__(self, parent):
+        super(OutputWidget, self).__init__(parent)
+        self.setReadOnly(True)
+        sys.stdout = self
+        sys.stderr = self
+        self.buf = u""
+        self.startTimer(500)
+
+        
+    def write(self, s):
+        sys.__stdout__.write(s)
+        self.buf += unicode(s)
+
+        
+    def writeline(self, s):
+        self.write(u"%s\n" % s)
+
+        
+    def timerEvent(self, event):
+        self.flush()
+
+        
+    def flush(self):
+        if self.buf:
+            if not self.window().isVisible():
+                self.window().show()
+            self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
+            self.textCursor().insertText(self.buf)          
+            self.moveCursor(QTextCursor.End, QTextCursor.MoveAnchor)
+            self.ensureCursorVisible()
+            self.buf = ""
+
+
+    
+class Console(QDialog):
+
+
+    def __init__(self, namespace=None):
+        QDialog.__init__(self)
+        if namespace is None:
+            namespace = {}
+        self.namespace = namespace
+        self.vblayout = QVBoxLayout(self)
+        self.splitter = QSplitter(Qt.Vertical, self)
+        self.layout().addWidget(self.splitter)
+        self.edit = EditorWidget(self.splitter)
+        self.edit.setPlainText(example)
+        self.output = OutputWidget(self.splitter)       
+        self.runButton = QPushButton(self, text="&Run")
+        self.runButton.clicked.connect(self.run)
+        self.layout().addWidget(self.runButton)
+        self.edit.setFocus()
+        self.resize(800, 600)
+        
+    def run(self):
+        code = unicode(self.edit.toPlainText())
+        try:
+            exec code in self.namespace
+        except Exception, e:
+            print "\n", "-"*40
+            print e
+            import traceback
+            traceback.print_exc()
+    
+        
+
+        
+
+        
+if __name__ == "__main__":
+    import sys
+    from PyQt4.QtGui import QApplication
+    app = QApplication(sys.argv)
+    win = Console()
+    win.show()
+    app.exec_()
+    

File embpyqt/python/embeddedpyqt/proxy.py

+# -*- coding: utf-8 -*-
+import sys
+
+from PyQt4.QtCore import QMetaMethod, pyqtSlot, QObject, QVariant, QString, QStringList
+
+
+def wrap_value(value):
+    if isinstance(value, QObject):
+        return wrap_instance(value)
+    elif isinstance(value, QString):
+        return unicode(value)
+    elif isinstance(value, QStringList):
+        return [unicode(v) for v in value]
+    elif isinstance(value, dict):
+        d = {}
+        for k, v in value.items():
+            d[unicode(v)] = wrap_value(v)
+        return d
+    elif isinstance(value, list):
+        return [wrap_value(v) for v in value]
+    else:
+        return value
+
+        
+
+
+
+class QtMethodCall(QObject):
+    
+
+    def __init__(self, obj, methods):
+        QObject.__init__(self)
+        self.obj = obj
+        self.methods = methods
+        
+        
+    def __repr__(self):
+        return "<instance method %r of %r>" % (self.methods.values()[0].name, self.obj)
+
+    
+    def _matching_method_for_signature(self, arg_types):
+        found = None
+        for i, (signature, method) in enumerate(self.methods.items()):
+            found = method
+            break # XXX: add real code here
+        if not found:
+            raise TypeError("No matching methods with given signature found")
+        return found
+
+
+    def __call__(self, *args, **kwargs):
+        if kwargs:
+            raise TypeError("Keyword arguments are not supported currently")
+        new_args = []
+        for a in args:
+            if isinstance(a, PyQtClass):
+                new_args.append(a._qt)
+            else:
+                new_args.append(a)
+        args = new_args
+        arg_types = [type(a) for a in args]
+        method = self._matching_method_for_signature(arg_types)
+        call = getattr(self.obj._qt, method.name)
+        result = call(*args)
+        return wrap_value(result)
+
+
+    @pyqtSlot()
+    def _parameterless_callback(self):
+        return self()
+
+
+
+
+class QtMethod(object):
+
+
+    def __init__(self, meta_method):
+        self._mm = meta_method
+        name, _sep, params = self._mm.signature().partition("(")
+        self.name = name
+        self.signature = params[:-1]
+        self.param_names = self._mm.parameterNames()
+        self.param_types = self._mm.parameterTypes()
+        self.return_type = self._mm.typeName()
+        self.method_type = self._mm.methodType()
+
+    
+    def __repr__(self):
+        return "%s %s(%s)" % (
+              self.return_type or "void", self.name, self.signature)
+
+              
+
+
+class QtMethodSignal(object):
+    
+
+    def __init__(self, obj, signal, signature=None):
+        self.obj = obj
+        self.signal = signal
+        self.signature = signature
+
+        
+    def __repr__(self):
+        return "<Signal %r of %r>" % (self.signal, self.obj)
+
+
+    def connect(self, callback):
+        signal = getattr(self.obj._qt, self.signal.name)
+        if isinstance(callback, QtMethodCall) and not self.signature:
+            # cannot guess empty signature  with __call__(*args,**kwargs)
+            signal.connect(callback._parameterless_callback)
+            return
+    
+        if self.signature:
+            signal[self.signature].connect(callback)
+        else:
+            signal.connect(callback)
+
+
+    def __getitem__(self, *args):
+        return self.__class__(self.obj, self.signal, signature=args)
+
+
+
+
+class QtMethodDispatcher(object):
+    
+
+    def __init__(self, name, methods):
+        self.name = name
+        self.methods = methods
+
+        
+    def __call__(self, *args, **kwargs):
+        raise TypeError("%r is not a static or class method" % self.name)
+
+        
+    def __repr__(self):
+        return "<QtMethod %r>" % self.name
+
+
+    def __get__(self, obj, cls):
+        if obj is None:
+            return self
+        signal = None
+        for method in self.methods.values():
+            if method.method_type == QMetaMethod.Signal:
+                signal = QtMethodSignal(obj, method)
+                break
+        # calls to the same method will be cached inside the object
+        if signal:
+            setattr(obj, self.name, signal)
+            return signal
+        else:
+            call = QtMethodCall(obj, self.methods)
+            setattr(obj, self.name, call)
+            return call
+
+
+
+
+class QtProperty(object):
+
+
+    def __init__(self, meta_property):
+        self._mp = meta_property
+        name = self._mp.name()
+        self.qt_name = name
+        self.name = name[0].upper() + name[1:]
+        self.type = self._mp.typeName()
+
+        
+    def __get__(self, obj, cls):
+        if obj is None:
+            return self
+        if isinstance(obj, PyQtClass):
+            obj = obj._qt
+        value = self._mp.read(obj)
+        return wrap_value(value)
+
+    
+    def __set__(self, obj, value):
+        if obj is None:
+            return
+        if isinstance(obj, PyQtClass):
+            obj = obj._qt
+        if isinstance(value, PyQtClass):
+            value = value._qt
+        self._mp.write(obj, value)
+
+
+
+
+class PyQtClass(object):
+    
+
+    def __init__(self, *args, **kwargs):
+        instance = kwargs.pop("_wrap_instance", None)
+        if not instance:
+            mo = self.__class__.__dict__["_metaobject"]
+            instance = mo.newInstance(*args, **kwargs)
+        self._qt = instance
+
+        
+    def __del__(self):
+        pass #print self, "deleted"
+
+
+    def __repr__(self):
+        mo = self.__class__.__dict__["_metaobject"]
+        return "<%s object %r>" % (mo.className(), unicode(self._qt.objectName()))
+
+    
+    def __iter__(self):
+        for child in self._qt.children():
+            yield wrap_instance(child)
+
+
+    def __getattr__(self, name):
+        # dynamic properties cannot be wrapped with QtProperty descriptors
+        pnames = [unicode(n) for n in self._qt.dynamicPropertyNames()]
+        qname = name[0].lower() + name[1:]
+        if qname in pnames:
+            value = self._qt.property(qname).toPyObject()
+            return wrap_value(value)
+
+        # access child objects as attribute
+        for child in self._qt.children():
+            if child.objectName() == name:
+                return wrap_instance(child)
+        # unknown
+        raise AttributeError("%s has not attribute %r" % (self, name))
+
+
+    def __setitem__(self, name, value):
+        # set dynamic property
+        if isinstance(value, PyQtClass):
+            value = value._qt
+        self._qt.setProperty(name, QVariant(value))
+
+
+def create_proxy_class(meta_object, bases=(PyQtClass,), attrs=None):
+    mo = meta_object
+    properties = {}
+    for pi in range(mo.propertyCount()):
+        meta_property = mo.property(pi)
+        p = QtProperty(meta_property)
+        properties[p.name] = p
+    methods = {}
+    for mi in range(mo.methodCount()):
+        meta_method = mo.method(mi)
+        m = QtMethod(meta_method)
+        methods.setdefault(m.name, {})[m.signature] = m
+    if attrs is None:
+        attrs = {}
+    for k, v in properties.items():
+        attrs[k] = v
+    attrs["_properties"] = properties
+    for k, v in methods.items():
+        attrs[k] = QtMethodDispatcher(k, v)
+    attrs["_methods"] = methods
+    attrs["_metaobject"] = meta_object
+    class_name = mo.className()
+    return type(class_name, bases, attrs)
+
+
+
+# cache classes
+_qt_classes = {}
+
+
+def class_from_metaobject(meta_object):
+    class_name = meta_object.className()
+    cls = _qt_classes.get(class_name, None)
+    if not cls:
+        cls = create_proxy_class(meta_object)
+        _qt_classes[class_name] = cls
+    return cls
+
+
+def wrap_instance(instance):
+    cls = class_from_metaobject(instance.metaObject())
+    return cls(_wrap_instance=instance)
+
+
+
+
+if __name__ == "__main__":
+    from PyQt4.QtCore import QObject
+    from PyQt4.QtGui import QApplication, QPushButton
+    _a = QApplication(sys.argv)
+    a = wrap_instance(_a)
+    
+    def on_click():
+        print "clicked!"
+        ap.quit()
+
+
+    _b = QPushButton(None)
+    b = wrap_instance(_b)
+    b.Text = "Click to close!"
+    b.clicked.connect(on_click)
+    
+    cls = class_from_metaobject(QObject.staticMetaObject)
+    print cls
+    t = cls()
+    t.ObjectName = "foo bar"
+    print t

File embpyqt/python/embeddedpyqt/stubgen.py

+# -*- coding: utf-8 -*-
+import keyword
+
+from PyQt4.QtCore import QMetaMethod, QObject
+from pyqtproxy import class_from_metaobject
+
+
+
+class CodeGenerator(object):
+	
+	
+	def __init__(self):
+		self.output = []
+		self.level = 0
+
+	
+	def indent(self, count=1):
+		self.level += count
+	
+		
+	def dedent(self, count=1):
+		self.level -= count
+	
+	
+	def begin(self, code=""):
+		if code:
+			self.emit(code)
+		self.indent()
+
+	
+	def end(self):
+		if self.output and self.output[-1] and self.output[-1][-1] == ":":
+			self.emit("pass")
+		self.dedent()
+
+
+	def emit(self, code):
+		indention = "  " * self.level
+		self.output.append(indention + code)
+
+
+	def prepend_header(self, code):
+		if code not in self.output:
+			self.output.insert(0, code)
+
+		
+	def newline(self, count=1):
+		self.output.extend([""]*count)
+
+
+	def __str__(self):
+		return "\n".join(["# coding: utf-8 -*-", "# created stub"] + self.output)
+	
+
+
+class StubCreator(object):
+
+	
+	def __init__(self):
+		self.codegen = CodeGenerator()
+		self.codegen.newline()
+
+	def add_class(self, cls):
+		if isinstance(cls, QObject):
+			pcls = class_from_metaobject(cls.staticMetaObject)
+		else:
+			pcls = cls
+		self.codegen.newline()
+		self.codegen.begin("class %s(object):" % pcls._metaobject.className())
+		self.codegen.newline()
+		qt_types = set()
+		# -- methods --
+		for method_name, methods in pcls._methods.items():
+			if method_name.startswith("_") or method_name in ("deleteLater",):
+				continue # skip private methods
+			for signature, method in methods.items():
+				param_names = map(unicode, method.param_names)
+				param_types = map(unicode, method.param_types)
+				for i, (pn, pt) in enumerate(zip(param_names, param_types)):
+					pt = self.fix_type(pt)
+					if pt.startswith("Q"):
+						qt_types.add(pt)
+					param_types[i] = pt
+					if not pn:
+						pn = "%s_%s" % (pt, i)
+						param_names[i] = pn
+				args = ["self"] + param_names
+				signature = ", ".join(args)
+				if method.method_type == QMetaMethod.Signal:
+					self.codegen.emit("%s = pyqtSignal(%s)" % (method_name, ", ".join(param_types)))
+				else:
+					self.codegen.begin("def %s(%s):" % (self.fix_name(method_name), signature))
+					for pname, ptype in zip(param_names, param_types):
+						self.codegen.emit("assert isinstance(%s, %s)" % (pname, ptype))
+					
+					rtype = unicode(method.return_type)
+					if rtype not in ("void", ""):
+						rtype = self.fix_type(rtype)
+						if rtype.startswith("Q"):
+							qt_types.add(rtype)
+						self.codegen.emit("return %s()" % rtype)
+					self.codegen.end()
+				self.codegen.newline()
+				break
+		# -- properties --
+		for property_name, prop in pcls._properties.items():
+			if property_name in ("destroyed",):
+				continue
+			ptype = self.fix_type(prop.type)
+			if ptype.startswith("Q"):
+				qt_types.add(ptype)
+
+			getter = pcls._methods.get(prop.qt_name, None)
+			setter = pcls._methods.get("set%s" % property_name, None)
+			if getter and setter:
+				self.codegen.emit("%s = property(fget=%s, fset=set%s)" % (property_name, prop.qt_name, property_name))
+			elif getter:
+				self.codegen.emit("%s = property(fget=%s)" % (property_name, prop.qt_name))
+			elif setter:
+				self.codegen.emit("%s = property(fset=set%s)" % (property_name, property_name))
+			else:
+				self.codegen.emit("%s = property()" % property_name)
+
+		self.codegen.newline()
+		self.codegen.begin("def __assert_property_types(self):")
+		self.codegen.emit("# gives source code analyzers hints about assumed type of property")
+		for property_name, prop in pcls._properties.items():
+			if property_name in ("destroyed",):
+				continue
+			ptype = self.fix_type(prop.type)
+			self.codegen.emit("assert isinstance(self.%s, %s)" % (property_name, ptype))
+		self.codegen.end()
+		self.codegen.end()
+		self.codegen.newline()
+		self.codegen.newline()
+		
+		# -- imports ---
+		import PyQt4.QtCore, PyQt4.QtGui
+		qt_modules = (PyQt4.QtCore, PyQt4.QtGui)
+		self.codegen.prepend_header("from PyQt4.QtCore import Qt, pyqtSignal")
+		for qtt in qt_types:
+			for mod in qt_modules:
+				if hasattr(mod, qtt):
+					self.codegen.prepend_header("from %s import %s" % (mod.__name__, qtt))
+					break
+		
+		
+	def fix_name(self, n):
+		if keyword.iskeyword(n):
+			return "%s_" % n
+		else:
+			return n
+
+		
+	def fix_type(self, t):
+		t = t.replace("&", "").replace("*", "").replace("::", ".")
+		if t == "QString":
+			t = "unicode"
+		return t
+
+	
+	def __str__(self):
+		return str(self.codegen)
+
+
+	
+if __name__ == "__main__":
+	from PyQt4.QtGui import QApplication, QPushButton
+	stubs = StubCreator()
+	stubs.add_class(QApplication)
+	stubs.add_class(QPushButton)
+	print stubs

File embpyqt/python/initembpyqt.py

+# -*- coding: utf-8 -*-
+import sys, os
+
+path = os.path.dirname(os.path.abspath(__file__))
+if path not in sys.path:
+	sys.path.insert(0, path)
+
+import embeddedpyqt
     EmbeddedPyQt *embpyqt;
     embpyqt = new EmbeddedPyQt();
     embpyqt->registerMetaObject(Test::staticMetaObject);
-    embpyqt->init("embeddedpyqt.py");
+    embpyqt->init("embpyqt/python/initembpyqt.py");
 
     return a.exec();
 }

File pyqtproxy.py

-# -*- coding: utf-8 -*-
-import sys
-
-from PyQt4.QtCore import QMetaMethod, pyqtSlot, QObject, QVariant, QString, QStringList
-
-
-def wrap_value(value):
-    if isinstance(value, QObject):
-        return wrap_instance(value)
-    elif isinstance(value, QString):
-        return unicode(value)
-    elif isinstance(value, QStringList):
-        return [unicode(v) for v in value]
-    elif isinstance(value, dict):
-        d = {}
-        for k, v in value.items():
-            d[unicode(v)] = wrap_value(v)
-        return d
-    elif isinstance(value, list):
-        return [wrap_value(v) for v in value]
-    else:
-        return value
-
-        
-
-
-
-class QtMethodCall(QObject):
-    
-
-    def __init__(self, obj, methods):
-        QObject.__init__(self)
-        self.obj = obj
-        self.methods = methods
-        
-        
-    def __repr__(self):
-        return "<instance method %r of %r>" % (self.methods.values()[0].name, self.obj)
-
-    
-    def _matching_method_for_signature(self, arg_types):
-        found = None
-        for i, (signature, method) in enumerate(self.methods.items()):
-            found = method
-            break # XXX: add real code here
-        if not found:
-            raise TypeError("No matching methods with given signature found")
-        return found
-
-
-    def __call__(self, *args, **kwargs):
-        if kwargs:
-            raise TypeError("Keyword arguments are not supported currently")
-        new_args = []
-        for a in args:
-            if isinstance(a, PyQtClass):
-                new_args.append(a._qt)
-            else:
-                new_args.append(a)
-        args = new_args
-        arg_types = [type(a) for a in args]
-        method = self._matching_method_for_signature(arg_types)
-        call = getattr(self.obj._qt, method.name)
-        result = call(*args)
-        return wrap_value(result)
-
-
-    @pyqtSlot()
-    def _parameterless_callback(self):
-        return self()
-
-
-
-
-class QtMethod(object):
-
-
-    def __init__(self, meta_method):
-        self._mm = meta_method
-        name, _sep, params = self._mm.signature().partition("(")
-        self.name = name
-        self.signature = params[:-1]
-        self.param_names = self._mm.parameterNames()
-        self.param_types = self._mm.parameterTypes()
-        self.return_type = self._mm.typeName()
-        self.method_type = self._mm.methodType()
-
-    
-    def __repr__(self):
-        return "%s %s(%s)" % (
-              self.return_type or "void", self.name, self.signature)
-
-              
-
-
-class QtMethodSignal(object):
-    
-
-    def __init__(self, obj, signal, signature=None):
-        self.obj = obj
-        self.signal = signal
-        self.signature = signature
-
-        
-    def __repr__(self):
-        return "<Signal %r of %r>" % (self.signal, self.obj)
-
-
-    def connect(self, callback):
-        signal = getattr(self.obj._qt, self.signal.name)
-        if isinstance(callback, QtMethodCall) and not self.signature:
-            # cannot guess empty signature  with __call__(*args,**kwargs)
-            signal.connect(callback._parameterless_callback)
-            return
-    
-        if self.signature:
-            signal[self.signature].connect(callback)
-        else:
-            signal.connect(callback)
-
-
-    def __getitem__(self, *args):
-        return self.__class__(self.obj, self.signal, signature=args)
-
-
-
-
-class QtMethodDispatcher(object):
-    
-
-    def __init__(self, name, methods):
-        self.name = name
-        self.methods = methods
-
-        
-    def __call__(self, *args, **kwargs):
-        raise TypeError("%r is not a static or class method" % self.name)
-
-        
-    def __repr__(self):
-        return "<QtMethod %r>" % self.name
-
-
-    def __get__(self, obj, cls):
-        if obj is None:
-            return self
-        signal = None
-        for method in self.methods.values():
-            if method.method_type == QMetaMethod.Signal:
-                signal = QtMethodSignal(obj, method)
-                break
-        # calls to the same method will be cached inside the object
-        if signal:
-            setattr(obj, self.name, signal)
-            return signal
-        else:
-            call = QtMethodCall(obj, self.methods)
-            setattr(obj, self.name, call)
-            return call
-
-
-
-
-class QtProperty(object):
-
-
-    def __init__(self, meta_property):
-        self._mp = meta_property
-        name = self._mp.name()
-        self.qt_name = name
-        self.name = name[0].upper() + name[1:]
-        self.type = self._mp.typeName()
-
-        
-    def __get__(self, obj, cls):
-        if obj is None:
-            return self
-        if isinstance(obj, PyQtClass):
-            obj = obj._qt
-        value = self._mp.read(obj)
-        return wrap_value(value)
-
-    
-    def __set__(self, obj, value):
-        if obj is None:
-            return
-        if isinstance(obj, PyQtClass):
-            obj = obj._qt
-        if isinstance(value, PyQtClass):
-            value = value._qt
-        self._mp.write(obj, value)
-
-
-
-
-class PyQtClass(object):
-    
-
-    def __init__(self, *args, **kwargs):
-        instance = kwargs.pop("_wrap_instance", None)
-        if not instance:
-            mo = self.__class__.__dict__["_metaobject"]
-            instance = mo.newInstance(*args, **kwargs)
-        self._qt = instance
-
-        
-    def __del__(self):
-        pass #print self, "deleted"
-
-
-    def __repr__(self):
-        mo = self.__class__.__dict__["_metaobject"]
-        return "<%s object %r>" % (mo.className(), unicode(self._qt.objectName()))
-
-    
-    def __iter__(self):
-        for child in self._qt.children():
-            yield wrap_instance(child)
-
-
-    def __getattr__(self, name):
-        # dynamic properties cannot be wrapped with QtProperty descriptors
-        pnames = [unicode(n) for n in self._qt.dynamicPropertyNames()]
-        qname = name[0].lower() + name[1:]
-        if qname in pnames:
-            value = self._qt.property(qname).toPyObject()
-            return wrap_value(value)
-
-        # access child objects as attribute
-        for child in self._qt.children():
-            if child.objectName() == name:
-                return wrap_instance(child)
-        # unknown
-        raise AttributeError("%s has not attribute %r" % (self, name))
-
-
-    def __setitem__(self, name, value):
-        # set dynamic property
-        if isinstance(value, PyQtClass):
-            value = value._qt
-        self._qt.setProperty(name, QVariant(value))
-
-
-def create_proxy_class(meta_object, bases=(PyQtClass,), attrs=None):
-    mo = meta_object
-    properties = {}
-    for pi in range(mo.propertyCount()):
-        meta_property = mo.property(pi)
-        p = QtProperty(meta_property)
-        properties[p.name] = p
-    methods = {}
-    for mi in range(mo.methodCount()):
-        meta_method = mo.method(mi)
-        m = QtMethod(meta_method)
-        methods.setdefault(m.name, {})[m.signature] = m
-    if attrs is None:
-        attrs = {}
-    for k, v in properties.items():
-        attrs[k] = v
-    attrs["_properties"] = properties
-    for k, v in methods.items():
-        attrs[k] = QtMethodDispatcher(k, v)
-    attrs["_methods"] = methods
-    attrs["_metaobject"] = meta_object
-    class_name = mo.className()
-    return type(class_name, bases, attrs)
-
-
-
-# cache classes
-_qt_classes = {}
-
-
-def class_from_metaobject(meta_object):
-    class_name = meta_object.className()
-    cls = _qt_classes.get(class_name, None)
-    if not cls:
-        cls = create_proxy_class(meta_object)
-        _qt_classes[class_name] = cls
-    return cls
-
-
-def wrap_instance(instance):
-    cls = class_from_metaobject(instance.metaObject())
-    return cls(_wrap_instance=instance)
-
-
-
-
-if __name__ == "__main__":
-    from PyQt4.QtCore import QObject
-    from PyQt4.QtGui import QApplication, QPushButton
-    _a = QApplication(sys.argv)
-    a = wrap_instance(_a)
-    
-    def on_click():
-        print "clicked!"
-        ap.quit()
-
-
-    _b = QPushButton(None)
-    b = wrap_instance(_b)
-    b.Text = "Click to close!"
-    b.clicked.connect(on_click)
-    
-    cls = class_from_metaobject(QObject.staticMetaObject)
-    print cls
-    t = cls()
-    t.ObjectName = "foo bar"
-    print t

File pyqtstubs.py

-# -*- coding: utf-8 -*-
-import keyword
-
-from PyQt4.QtCore import QMetaMethod, QObject
-from pyqtproxy import class_from_metaobject
-
-
-
-class CodeGenerator(object):
-	
-	
-	def __init__(self):
-		self.output = []
-		self.level = 0
-
-	
-	def indent(self, count=1):
-		self.level += count
-	
-		
-	def dedent(self, count=1):
-		self.level -= count
-	
-	
-	def begin(self, code=""):
-		if code:
-			self.emit(code)
-		self.indent()
-
-	
-	def end(self):
-		if self.output and self.output[-1] and self.output[-1][-1] == ":":
-			self.emit("pass")
-		self.dedent()
-
-
-	def emit(self, code):
-		indention = "  " * self.level
-		self.output.append(indention + code)
-
-
-	def prepend_header(self, code):
-		if code not in self.output:
-			self.output.insert(0, code)
-
-		
-	def newline(self, count=1):
-		self.output.extend([""]*count)
-
-
-	def __str__(self):
-		return "\n".join(["# coding: utf-8 -*-", "# created stub"] + self.output)
-	
-
-
-class StubCreator(object):
-
-	
-	def __init__(self):
-		self.codegen = CodeGenerator()
-		self.codegen.newline()
-
-	def add_class(self, cls):
-		if isinstance(cls, QObject):
-			pcls = class_from_metaobject(cls.staticMetaObject)
-		else:
-			pcls = cls
-		self.codegen.newline()
-		self.codegen.begin("class %s(object):" % pcls._metaobject.className())
-		self.codegen.newline()
-		qt_types = set()
-		# -- methods --
-		for method_name, methods in pcls._methods.items():
-			if method_name.startswith("_") or method_name in ("deleteLater",):
-				continue # skip private methods
-			for signature, method in methods.items():
-				param_names = map(unicode, method.param_names)
-				param_types = map(unicode, method.param_types)
-				for i, (pn, pt) in enumerate(zip(param_names, param_types)):
-					pt = self.fix_type(pt)
-					if pt.startswith("Q"):
-						qt_types.add(pt)
-					param_types[i] = pt
-					if not pn:
-						pn = "%s_%s" % (pt, i)
-						param_names[i] = pn
-				args = ["self"] + param_names
-				signature = ", ".join(args)
-				if method.method_type == QMetaMethod.Signal:
-					self.codegen.emit("%s = pyqtSignal(%s)" % (method_name, ", ".join(param_types)))
-				else:
-					self.codegen.begin("def %s(%s):" % (self.fix_name(method_name), signature))
-					for pname, ptype in zip(param_names, param_types):
-						self.codegen.emit("assert isinstance(%s, %s)" % (pname, ptype))
-					
-					rtype = unicode(method.return_type)
-					if rtype not in ("void", ""):
-						rtype = self.fix_type(rtype)
-						if rtype.startswith("Q"):
-							qt_types.add(rtype)
-						self.codegen.emit("return %s()" % rtype)
-					self.codegen.end()
-				self.codegen.newline()
-				break
-		# -- properties --
-		for property_name, prop in pcls._properties.items():
-			if property_name in ("destroyed",):
-				continue
-			ptype = self.fix_type(prop.type)
-			if ptype.startswith("Q"):
-				qt_types.add(ptype)
-
-			getter = pcls._methods.get(prop.qt_name, None)
-			setter = pcls._methods.get("set%s" % property_name, None)
-			if getter and setter:
-				self.codegen.emit("%s = property(fget=%s, fset=set%s)" % (property_name, prop.qt_name, property_name))
-			elif getter:
-				self.codegen.emit("%s = property(fget=%s)" % (property_name, prop.qt_name))
-			elif setter:
-				self.codegen.emit("%s = property(fset=set%s)" % (property_name, property_name))
-			else:
-				self.codegen.emit("%s = property()" % property_name)
-
-		self.codegen.newline()
-		self.codegen.begin("def __assert_property_types(self):")
-		self.codegen.emit("# gives source code analyzers hints about assumed type of property")
-		for property_name, prop in pcls._properties.items():
-			if property_name in ("destroyed",):
-				continue
-			ptype = self.fix_type(prop.type)
-			self.codegen.emit("assert isinstance(self.%s, %s)" % (property_name, ptype))
-		self.codegen.end()
-		self.codegen.end()
-		self.codegen.newline()
-		self.codegen.newline()
-		
-		# -- imports ---
-		import PyQt4.QtCore, PyQt4.QtGui
-		qt_modules = (PyQt4.QtCore, PyQt4.QtGui)
-		self.codegen.prepend_header("from PyQt4.QtCore import Qt, pyqtSignal")
-		for qtt in qt_types:
-			for mod in qt_modules:
-				if hasattr(mod, qtt):
-					self.codegen.prepend_header("from %s import %s" % (mod.__name__, qtt))
-					break
-		
-		
-	def fix_name(self, n):
-		if keyword.iskeyword(n):
-			return "%s_" % n
-		else:
-			return n
-
-		
-	def fix_type(self, t):
-		t = t.replace("&", "").replace("*", "").replace("::", ".")
-		if t == "QString":
-			t = "unicode"
-		return t
-
-	
-	def __str__(self):
-		return str(self.codegen)
-
-
-	
-if __name__ == "__main__":
-	from PyQt4.QtGui import QApplication, QPushButton
-	stubs = StubCreator()
-	stubs.add_class(QApplication)
-	stubs.add_class(QPushButton)
-	print stubs