Commits

Henning Schröder  committed d60e78a

static meta object can now be used to create instances of C++ classes from python

  • Participants
  • Parent commits 685a274

Comments (0)

Files changed (7)

File embeddedpyqt.pro

 TEMPLATE = app
 
 SOURCES += main.cpp\
-        mainwindow.cpp
-HEADERS  += mainwindow.h
+        mainwindow.cpp \
+    test.cpp
+HEADERS  += mainwindow.h \
+    test.h
 FORMS    += mainwindow.ui
 
 # Python support
 HEADERS += \
     embpyqt/embeddedpyqt.h \
     embpyqt/pythonize.h
-

File embeddedpyqt.py

 import sys
-from PyQt4.QtGui import qApp
-from PyQt4.QtCore import QMetaType, QMetaObject
+from PyQt4.QtGui import qApp, QWidget, QPushButton
+from PyQt4.QtCore import QMetaType, QMetaObject, Q_ARG
 import sip
 
 def on_error(*args):
 
 embpyqt = qApp.property("embedded_pyqt").toPyObject()
 
-ptr = embpyqt.metaObjectByName("QPushButton")
+ptr = embpyqt.metaObjectByName("Test")
 mo = sip.wrapinstance(int(ptr), QMetaObject)
-print mo.className()
-w = mo.newInstance(qApp.activeWindow())
-print w
-
+print "mo classname", mo.className()
+o = mo.newInstance()
+print "new", o
+o.test()
+print "1+2", o.calc(1,2)
 embpyqt.setException("foo", "baz")
 
 
+
 print "done"
-1/0
+1/0

File embpyqt/embeddedpyqt.cpp

 #include <QPushButton>
 #include <qdebug.h>
 
-
+#include "test.h"
 
 EmbeddedPyQt::EmbeddedPyQt(QObject *parent) :
     QObject(parent)
 {
     setObjectName("embeddedPyQt");
     //REGISTER(QObject);
-    classes["QObject"] = &QObject::staticMetaObject;
-    classes["QPushButton"] = &QPushButton::staticMetaObject;
+    //EmbeddedPyQt::instance = this;
+    classes["Test"] = &Test::staticMetaObject;
 
-    //EmbeddedPyQt::instance = this;
+
     python = new Pythonize();
     Q_ASSERT(python);
     QApplication::instance()->setProperty("embedded_pyqt",
 
     EmbeddedPyQt *embpyqt;
     embpyqt = new EmbeddedPyQt();
+
+
     return a.exec();
 }
 

File pyqtproxy.py

+import sys
+from PyQt4.QtGui import QApplication, QPushButton
+
+
+
+class QtMethodCall(object):
+	
+	def __init__(self, obj):
+		self._obj = obj
+		
+	def __call__(self, *args, **kwargs):
+		if kwargs:
+			raise TypeError
+		return self._obj.invoke(args)
+
+
+class QtMethod(object):
+
+
+	def __init__(self, meta_method):
+		self._mm = meta_method
+		self.name = self._mm.name()
+		self.signature = self._mm.signature()
+
+
+	def __get__(self, obj, cls):
+		if obj is None:
+			return self
+		return QtMethodCall(obj)
+
+
+class QtProperty(object):
+	
+	def __init__(self, meta_property):
+		self._mp = meta_property
+		self.name = self._mp.name()
+		self.type = self._mp.type()
+
+		
+	def __get__(self, obj, cls):
+		if obj is None:
+			return self
+		if isinstance(obj, QtProxy):
+			obj = obj._qt
+		return self._mp.read(obj)
+
+	
+	def __set__(self, obj, cls, value):
+		if obj is None:
+			return
+		if isinstance(obj, QtProxy):
+			obj = obj._qt
+		self._mp.write(obj, value)
+
+
+class QtProxy(object):
+	
+	def __init____(self, qt_object):
+		self._qt = qt_object
+		mo = self._qt.metaObject()
+		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[(m.name, m.signature)] = m
+	
+
+	def __getattr__(self, name):
+		try:
+			return getattr(self._qt, name)
+		except AttributeError:
+			return self._qt.property(name)
+		
+	
+	
+	
+
+	
+
+a = QApplication(sys.argv)
+b = QPushButton(None)
+p = QtProxy(b)
+print dir(b)
+#include "test.h"
+#include <qdebug.h>
+
+
+Test::Test() :
+    QObject(0)
+{
+
+}
+
+
+void Test::test() {
+    qDebug() << "Test!";
+}
+
+int Test::calc(int a, int b) {
+    return a + b;
+}
+#ifndef TEST_H
+#define TEST_H
+
+#include <QObject>
+
+class Test : public QObject
+{
+    Q_OBJECT
+public:
+
+    Q_INVOKABLE explicit Test();
+
+signals:
+
+public slots:
+    void test();
+    int calc(int a, int b);
+};
+
+#endif // TEST_H