diff --git a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp index 8bf55c047..61d3083ee 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp +++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp @@ -545,39 +545,40 @@ void PythonContext::setGlobal(const char *varName, QWidget *object) setQtGlobal(varName, object); } -void PythonContext::setQtGlobal_internal(const char *varName, const char *typeName, QObject *object) +QWidget *PythonContext::QWidgetFromPy(PyObject *widget) { #if PYSIDE2_ENABLED if(!initialised()) - { - emit exception( - "SystemError", - "Python integration failed to initialise, see diagnostic log for more information.", {}); - return; - } + return NULL; if(!SbkPySide2_QtCoreTypes || !SbkPySide2_QtGuiTypes || !SbkPySide2_QtWidgetsTypes) - { - emit exception("SystemError", - "PySide Qt library didn't load, see diagnostic log for more information.", {}); - return; - } + return NULL; + + if(!Shiboken::Object::checkType(widget)) + return NULL; + + return (QWidget *)Shiboken::Object::cppPointer((SbkObject *)widget, Shiboken::SbkType()); +#else + return NULL; +#endif +} + +PyObject *PythonContext::QtObjectToPython(const char *typeName, QObject *object) +{ +#if PYSIDE2_ENABLED + if(!initialised()) + return NULL; + + if(!SbkPySide2_QtCoreTypes || !SbkPySide2_QtGuiTypes || !SbkPySide2_QtWidgetsTypes) + return NULL; PyObject *obj = Shiboken::Object::newObject(reinterpret_cast(Shiboken::SbkType()), object, false, false, typeName); - if(!obj) - { - emit exception("RuntimeError", - QString("Failed to set variable '%1' of type '%2'").arg(varName).arg(typeName), - {}); - return; - } - - setPyGlobal(varName, obj); + return obj; #else - emit exception("SystemError", "PySide2 was not enabled at build-time, cannot set Qt variable.", {}); + return NULL; #endif } diff --git a/qrenderdoc/Code/pyrenderdoc/PythonContext.h b/qrenderdoc/Code/pyrenderdoc/PythonContext.h index ba1c747d7..81d99ba3a 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonContext.h +++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.h @@ -64,10 +64,22 @@ public: template void setQtGlobal(const char *varName, QtObjectType *object) { + const char *typeName = typeid(*const_cast(object)).name(); + // forward non-template part on - setQtGlobal_internal(varName, typeid(*const_cast(object)).name(), object); + PyObject *obj = QtObjectToPython(typeName, object); + + if(obj) + setPyGlobal(varName, obj); + else + emit exception("RuntimeError", + QString("Failed to set variable '%1' of type '%2'").arg(varName).arg(typeName), + {}); } + static PyObject *QWidgetToPy(QWidget *widget) { return QtObjectToPython("QWidget", widget); } + static QWidget *QWidgetFromPy(PyObject *widget); + QString currentFile() { return location.file; } int currentLine() { return location.line; } signals: @@ -103,7 +115,7 @@ private: int line = 0; } location; - void setQtGlobal_internal(const char *varName, const char *typeName, QObject *object); + static PyObject *QtObjectToPython(const char *typeName, QObject *object); // Python callbacks static void outstream_del(PyObject *self); diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i index e43b9b483..d7b2bd126 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i @@ -24,6 +24,15 @@ CONTAINER_TYPEMAPS(QMap &) CONTAINER_TYPEMAPS(QMap *) CONTAINER_TYPEMAPS(QMap) +// pass QWidget objects to PySide +%typemap(in) QWidget * { + $1 = PythonContext::QWidgetFromPy($input); +} + +%typemap(out) QWidget * { + $result = PythonContext::QWidgetToPy($1); +} + // need to ignore the original function and add a helper that releases the python GIL while calling %ignore IRenderManager::BlockInvoke; @@ -47,6 +56,7 @@ CONTAINER_TYPEMAPS(QMap) #include "datetime.h" #include "Code/Interface/QRDInterface.h" + #include "Code/pyrenderdoc/PythonContext.h" %} %include