##// END OF EJS Templates
florianlink -
r161:87322f2ddb44
parent child
Show More
@@ -45,6 +45,7
45 45 #include "PythonQtMethodInfo.h"
46 46 #include "PythonQtSignalReceiver.h"
47 47 #include "PythonQtConversion.h"
48 #include "PythonQtStdIn.h"
48 49 #include "PythonQtStdOut.h"
49 50 #include "PythonQtCppWrapperFactory.h"
50 51 #include "PythonQtVariants.h"
@@ -142,6 +143,8 void PythonQt::cleanup()
142 143 }
143 144 }
144 145
146 PythonQt* PythonQt::self() { return _self; }
147
145 148 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
146 149 {
147 150 _p = new PythonQtPrivate;
@@ -150,7 +153,7 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
150 153 _p->_PythonQtObjectPtr_metaId = qRegisterMetaType<PythonQtObjectPtr>("PythonQtObjectPtr");
151 154
152 155 if ((flags & PythonAlreadyInitialized) == 0) {
153 Py_SetProgramName("PythonQt");
156 Py_SetProgramName(const_cast<char*>("PythonQt"));
154 157 if (flags & IgnoreSiteModule) {
155 158 // this prevents the automatic importing of Python site files
156 159 Py_NoSiteFlag = 1;
@@ -185,6 +188,12 PythonQt::PythonQt(int flags, const QByteArray& pythonQtModuleName)
185 188 }
186 189 Py_INCREF(&PythonQtStdOutRedirectType);
187 190
191 // add our own python object types for redirection of stdin
192 if (PyType_Ready(&PythonQtStdInRedirectType) < 0) {
193 std::cerr << "could not initialize PythonQtStdInRedirectType" << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
194 }
195 Py_INCREF(&PythonQtStdInRedirectType);
196
188 197 initPythonQtModule(flags & RedirectStdOut, pythonQtModuleName);
189 198
190 199 _p->setupSharedLibrarySuffixes();
@@ -213,6 +222,46 PythonQtPrivate::~PythonQtPrivate() {
213 222 PythonQtMethodInfo::cleanupCachedMethodInfos();
214 223 }
215 224
225 void PythonQt::setRedirectStdInCallback(PythonQtInputChangedCB* callback, void * callbackData)
226 {
227 if (!callback)
228 {
229 std::cerr << "PythonQt::setRedirectStdInCallback - callback parameter is NULL !" << std::endl;
230 return;
231 }
232
233 PythonQtObjectPtr sys;
234 PythonQtObjectPtr in;
235 sys.setNewRef(PyImport_ImportModule("sys"));
236
237 // Backup original 'sys.stdin' if not yet done
238 PyRun_SimpleString("if not hasattr(sys, 'pythonqt_original_stdin'):"
239 "sys.pythonqt_original_stdin = sys.stdin");
240
241 in = PythonQtStdInRedirectType.tp_new(&PythonQtStdInRedirectType, NULL, NULL);
242 ((PythonQtStdInRedirect*)in.object())->_cb = callback;
243 ((PythonQtStdInRedirect*)in.object())->_callData = callbackData;
244 // replace the built in file objects with our own objects
245 PyModule_AddObject(sys, "stdin", in);
246
247 // Backup custom 'stdin' into 'pythonqt_stdin'
248 PyRun_SimpleString("sys.pythonqt_stdin = sys.stdin");
249 }
250
251 void PythonQt::setRedirectStdInCallbackEnabled(bool enabled)
252 {
253 if (enabled)
254 {
255 PyRun_SimpleString("if hasattr(sys, 'pythonqt_stdin'):"
256 "sys.stdin = sys.pythonqt_stdin");
257 }
258 else
259 {
260 PyRun_SimpleString("if hasattr(sys,'pythonqt_original_stdin'):"
261 "sys.stdin = sys.pythonqt_original_stdin");
262 }
263 }
264
216 265 PythonQtImportFileInterface* PythonQt::importInterface()
217 266 {
218 267 return _self->_p->_importInterface?_self->_p->_importInterface:_self->_p->_defaultImporter;
@@ -365,6 +414,9 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
365 414 // if we a have a QObject wrapper and the metaobjects do not match, set the metaobject again!
366 415 info->setMetaObject(wrapper->metaObject());
367 416 }
417
418 // TODO XXX: delegate wrapping via CB here (pass name and ptr)
419
368 420 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
369 421 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
370 422 } else {
@@ -1065,11 +1117,19 void PythonQt::setModuleImportPath(PyObject* module, const QStringList& paths)
1065 1117
1066 1118 void PythonQt::stdOutRedirectCB(const QString& str)
1067 1119 {
1120 if (!PythonQt::self()) {
1121 std::cout << str.toLatin1().data() << std::endl;
1122 return;
1123 }
1068 1124 emit PythonQt::self()->pythonStdOut(str);
1069 1125 }
1070 1126
1071 1127 void PythonQt::stdErrRedirectCB(const QString& str)
1072 1128 {
1129 if (!PythonQt::self()) {
1130 std::cerr << str.toLatin1().data() << std::endl;
1131 return;
1132 }
1073 1133 emit PythonQt::self()->pythonStdErr(str);
1074 1134 }
1075 1135
@@ -47,6 +47,7
47 47 #include "PythonQtClassWrapper.h"
48 48 #include "PythonQtSlot.h"
49 49 #include "PythonQtObjectPtr.h"
50 #include "PythonQtStdIn.h"
50 51 #include <QObject>
51 52 #include <QVariant>
52 53 #include <QList>
@@ -71,11 +72,14 typedef void* PythonQtPolymorphicHandlerCB(const void *ptr, char **class_name);
71 72
72 73 typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper);
73 74
74 template<class T> void PythonQtSetInstanceWrapperOnShell(void* object, PythonQtInstanceWrapper* wrapper) { ((T*)object)->_wrapper = wrapper; };
75 template<class T> void PythonQtSetInstanceWrapperOnShell(void* object, PythonQtInstanceWrapper* wrapper) {
76 (reinterpret_cast<T*>(object))->_wrapper = wrapper;
77 }
75 78
76 79 //! returns the offset that needs to be added to upcast an object of type T1 to T2
77 80 template<class T1, class T2> int PythonQtUpcastingOffset() {
78 return (((char*)(static_cast<T2*>(reinterpret_cast<T1*>(0x100)))) - ((char*)reinterpret_cast<T1*>(0x100)));
81 return ((reinterpret_cast<char*>(static_cast<T2*>(reinterpret_cast<T1*>(0x100))))
82 - (reinterpret_cast<char*>(reinterpret_cast<T1*>(0x100))));
79 83 }
80 84
81 85 //! callback to create a QObject lazily
@@ -166,7 +170,7 public:
166 170 static void cleanup();
167 171
168 172 //! get the singleton instance
169 static PythonQt* self() { return _self; }
173 static PythonQt* self();
170 174
171 175 //@}
172 176
@@ -180,6 +184,21 public:
180 184 CallOverloads
181 185 };
182 186
187
188 //---------------------------------------------------------------------------
189 //! \name Standard input handling
190 //@{
191
192 //! Overwrite default handling of stdin using a custom callback. It internally backup
193 //! the original 'sys.stdin' into 'sys.pythonqt_original_stdin'
194 void setRedirectStdInCallback(PythonQtInputChangedCB* callback, void * callbackData = 0);
195
196 //! Enable or disable stdin custom callback. It resets 'sys.stdin' using either 'sys.pythonqt_stdin'
197 //! or 'sys.pythonqt_original_stdin'
198 void setRedirectStdInCallbackEnabled(bool enabled);
199
200 //@}
201
183 202 //---------------------------------------------------------------------------
184 203 //! \name Modules
185 204 //@{
@@ -42,7 +42,7
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include <Python.h>
45 #include "PythonQtPythonInclude.h"
46 46
47 47 #include "PythonQtSystem.h"
48 48
@@ -386,7 +386,9 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
386 386 } else if (info.name == "PyObject") {
387 387 // handle low level PyObject directly
388 388 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
389 } else if (obj == Py_None) {
389 }
390 // TODO XXX: pass obj and name and add when it returns a pointer
391 else if (obj == Py_None) {
390 392 // None is treated as a NULL ptr
391 393 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
392 394 } else {
@@ -673,15 +675,11 QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
673 675 if (val->ob_type == &PyString_Type) {
674 676 r = QString(PyString_AS_STRING(val));
675 677 } else if (PyUnicode_Check(val)) {
676 #ifdef WIN32
677 r = QString::fromUtf16(PyUnicode_AS_UNICODE(val));
678 #else
679 678 PyObject *ptmp = PyUnicode_AsUTF8String(val);
680 679 if(ptmp) {
681 680 r = QString::fromUtf8(PyString_AS_STRING(ptmp));
682 681 Py_DECREF(ptmp);
683 682 }
684 #endif
685 683 } else if (!strict) {
686 684 // EXTRA: could also use _Unicode, but why should we?
687 685 PyObject* str = PyObject_Str(val);
@@ -1038,12 +1036,7 PyObject* PythonQtConv::QStringToPyObject(const QString& str)
1038 1036 if (str.isNull()) {
1039 1037 return PyString_FromString("");
1040 1038 } else {
1041 #ifdef WIN32
1042 // return PyString_FromString(str.toLatin1().data());
1043 return PyUnicode_FromUnicode(str.utf16(), str.length());
1044 #else
1045 1039 return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
1046 #endif
1047 1040 }
1048 1041 }
1049 1042
@@ -791,7 +791,7 void PythonQtImport::init()
791 791 mod = Py_InitModule4("PythonQtImport", NULL, mlabimport_doc,
792 792 NULL, PYTHON_API_VERSION);
793 793
794 PythonQtImportError = PyErr_NewException("PythonQtImport.PythonQtImportError",
794 PythonQtImportError = PyErr_NewException(const_cast<char*>("PythonQtImport.PythonQtImportError"),
795 795 PyExc_ImportError, NULL);
796 796 if (PythonQtImportError == NULL)
797 797 return;
@@ -808,7 +808,7 void PythonQtImport::init()
808 808
809 809 // set our importer into the path_hooks to handle all path on sys.path
810 810 PyObject* classobj = PyDict_GetItemString(PyModule_GetDict(mod), "PythonQtImporter");
811 PyObject* path_hooks = PySys_GetObject("path_hooks");
811 PyObject* path_hooks = PySys_GetObject(const_cast<char*>("path_hooks"));
812 812 PyList_Append(path_hooks, classobj);
813 813
814 814 #ifndef WIN32
@@ -42,7 +42,8
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include "Python.h"
45 #include "PythonQtPythonInclude.h"
46
46 47 #include "structmember.h"
47 48 #include "osdefs.h"
48 49 #include "marshal.h"
@@ -42,7 +42,7
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include <Python.h>
45 #include "PythonQtPythonInclude.h"
46 46
47 47 #include "PythonQtSystem.h"
48 48 #include <QPointer>
@@ -98,3 +98,4 int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args
98 98 PyObject *PythonQtInstanceWrapper_delete(PythonQtInstanceWrapper * self);
99 99
100 100 #endif
101
@@ -41,6 +41,25
41 41
42 42 #include <PythonQt.h>
43 43
44 PythonQtObjectPtr::PythonQtObjectPtr(PyObject* o)
45 {
46 _object = o;
47 if (o) Py_INCREF(_object);
48 }
49
50 PythonQtObjectPtr::~PythonQtObjectPtr()
51 {
52 if (_object) Py_DECREF(_object);
53 }
54
55 void PythonQtObjectPtr::setNewRef(PyObject* o)
56 {
57 if (o != _object) {
58 if (_object) Py_DECREF(_object);
59 _object = o;
60 }
61 }
62
44 63 QVariant PythonQtObjectPtr::evalScript(const QString& script, int start)
45 64 {
46 65 return PythonQt::self()->evalScript(_object, script, start);
@@ -97,5 +116,13 bool PythonQtObjectPtr::fromVariant(const QVariant& variant)
97 116 setObject(0);
98 117 return false;
99 118 }
119 }
100 120
121 void PythonQtObjectPtr::setObject(PyObject* o)
122 {
123 if (o != _object) {
124 if (_object) Py_DECREF(_object);
125 _object = o;
126 if (_object) Py_INCREF(_object);
127 }
101 128 }
@@ -42,7 +42,8
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include <Python.h>
45 #include "PythonQtPythonInclude.h"
46
46 47 #include "PythonQtSystem.h"
47 48 #include <QVariant>
48 49 #include <QVariantList>
@@ -53,7 +54,8 class PYTHONQT_EXPORT PythonQtObjectPtr
53 54 public:
54 55 PythonQtObjectPtr():_object(NULL) {}
55 56
56 PythonQtObjectPtr(const PythonQtObjectPtr &p):_object(NULL) {
57 PythonQtObjectPtr(const PythonQtObjectPtr &p)
58 :_object(NULL) {
57 59 setObject(p.object());
58 60 }
59 61
@@ -62,12 +64,9 public:
62 64 fromVariant(variant);
63 65 }
64 66
65 PythonQtObjectPtr(PyObject* o) {
66 _object = o;
67 if (o) Py_INCREF(_object);
68 }
67 PythonQtObjectPtr(PyObject* o);
69 68
70 ~PythonQtObjectPtr() { if (_object) { Py_DECREF(_object); } }
69 ~PythonQtObjectPtr();
71 70
72 71 //! If the given variant holds a PythonQtObjectPtr, extract the value from it and hold onto the reference. This results in an increment of the reference count.
73 72 bool fromVariant(const QVariant& variant);
@@ -114,12 +113,7 public:
114 113 operator PyObject*() const { return object(); }
115 114
116 115 //! sets the object and passes the ownership (stealing the reference, in Python slang)
117 void setNewRef(PyObject* o) {
118 if (o != _object) {
119 if (_object) { Py_DECREF(_object); }
120 _object = o;
121 }
122 }
116 void setNewRef(PyObject* o);
123 117
124 118 PyObject* object() const {
125 119 return _object;
@@ -155,13 +149,7 public:
155 149
156 150 protected:
157 151
158 void setObject(PyObject* o) {
159 if (o != _object) {
160 if (_object) { Py_DECREF(_object); }
161 _object = o;
162 if (_object) { Py_INCREF(_object); }
163 }
164 }
152 void setObject(PyObject* o);
165 153
166 154 private:
167 155 PyObject* _object;
@@ -172,3 +160,4 private:
172 160 Q_DECLARE_METATYPE(PythonQtObjectPtr)
173 161
174 162 #endif
163
@@ -42,7 +42,8
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include <Python.h>
45 #include "PythonQtPythonInclude.h"
46
46 47 #include "PythonQtSystem.h"
47 48 #include "PythonQtObjectPtr.h"
48 49
@@ -364,7 +364,7 PythonQtSlotInfo*
364 364 PythonQtSlotFunction_GetSlotInfo(PyObject *op)
365 365 {
366 366 if (!PythonQtSlotFunction_Check(op)) {
367 PyErr_BadInternalCall();
367 PyErr_Format(PyExc_SystemError, "%s:%d: bad argument to internal function", __FILE__, __LINE__);
368 368 return NULL;
369 369 }
370 370 return ((PythonQtSlotFunctionObject *)op) -> m_ml;
@@ -374,7 +374,7 PyObject *
374 374 PythonQtSlotFunction_GetSelf(PyObject *op)
375 375 {
376 376 if (!PythonQtSlotFunction_Check(op)) {
377 PyErr_BadInternalCall();
377 PyErr_Format(PyExc_SystemError, "%s:%d: bad argument to internal function", __FILE__, __LINE__);
378 378 return NULL;
379 379 }
380 380 return ((PythonQtSlotFunctionObject *)op) -> m_self;
@@ -439,9 +439,9 meth_get__self__(PythonQtSlotFunctionObject *m, void * /*closure*/)
439 439 }
440 440
441 441 static PyGetSetDef meth_getsets [] = {
442 {"__doc__", (getter)meth_get__doc__, NULL, NULL},
443 {"__name__", (getter)meth_get__name__, NULL, NULL},
444 {"__self__", (getter)meth_get__self__, NULL, NULL},
442 {const_cast<char*>("__doc__"), (getter)meth_get__doc__, NULL, NULL},
443 {const_cast<char*>("__name__"), (getter)meth_get__name__, NULL, NULL},
444 {const_cast<char*>("__self__"), (getter)meth_get__self__, NULL, NULL},
445 445 {NULL, NULL, NULL,NULL},
446 446 };
447 447
@@ -452,7 +452,7 static PyGetSetDef meth_getsets [] = {
452 452 #define OFF(x) offsetof(PythonQtSlotFunctionObject, x)
453 453
454 454 static PyMemberDef meth_members[] = {
455 {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
455 {const_cast<char*>("__module__"), T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
456 456 {NULL}
457 457 };
458 458
@@ -42,7 +42,8
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include "Python.h"
45 #include "PythonQtPythonInclude.h"
46
46 47 #include "PythonQtSystem.h"
47 48 #include "structmember.h"
48 49
@@ -42,8 +42,10
42 42 */
43 43 //----------------------------------------------------------------------------------
44 44
45 #include "PythonQtPythonInclude.h"
46
45 47 #include "PythonQtSystem.h"
46 #include <Python.h>
48
47 49 #include <QObject>
48 50 #include <QVariantList>
49 51 #include <QTextDocument>
@@ -87,8 +87,8 static PyMethodDef PythonQtStdOutRedirect_methods[] = {
87 87 };
88 88
89 89 static PyMemberDef PythonQtStdOutRedirect_members[] = {
90 {"softspace", T_INT, offsetof(PythonQtStdOutRedirect, softspace), 0,
91 "soft space flag"
90 {const_cast<char*>("softspace"), T_INT, offsetof(PythonQtStdOutRedirect, softspace), 0,
91 const_cast<char*>("soft space flag")
92 92 },
93 93 {NULL} /* Sentinel */
94 94 };
@@ -43,7 +43,8
43 43 //----------------------------------------------------------------------------------
44 44
45 45
46 #include <Python.h>
46 #include "PythonQtPythonInclude.h"
47
47 48 #include "structmember.h"
48 49 #include <QString>
49 50
@@ -147,3 +147,4 private:
147 147
148 148
149 149 #endif
150
General Comments 0
You need to be logged in to leave comments. Login now