Discussion:
Obtaining QObject from PySide based PyObject (complete)
David García Garzón
2012-08-27 19:12:27 UTC
Permalink
Sorry for the previous unfinished message. Here goes the final one.

I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.

Does anyone know how recover the C++ QObject from the PyObject in PySide?

Thanks.
David.

PS: If someone is curious the current sip unwrapper, based on some snippets i
found, is in here:
http://clam-project.org/clam/trunk/ipyclam/sipunwrap.cxx
And the function which uses it is bindUi in
http://clam-project.org/clam/trunk/ipyclam/Clam_NetworkProxy.cxx
Hugo Parente Lima
2012-08-27 19:23:03 UTC
Permalink
Post by David García Garzón
Sorry for the previous unfinished message. Here goes the final one.
I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.
Does anyone know how recover the C++ QObject from the PyObject in PySide?
You can use:
Shiboken::Object::cppPointer(...), it's on libshiboken basewrapper.h

It receives two parameters, a SbkObject* and a PyTypeObject*, the SbkObject*
will be your PyObject*, just cast it and make sure it always will be a Python
object representing a C++ object bound using Shiboken, the PyTypeObject* must
be the PyTypeObject* for QObject, you can get it using:

Shiboken::TypeResolver::get("QObject*")->pythonType();

TypeResolver class is located on libshiboken typeresolver.h header.

Hope this would help you.
Post by David García Garzón
Thanks.
David.
PS: If someone is curious the current sip unwrapper, based on some snippets
http://clam-project.org/clam/trunk/ipyclam/sipunwrap.cxx
And the function which uses it is bindUi in
http://clam-project.org/clam/trunk/ipyclam/Clam_NetworkProxy.cxx
_______________________________________________
PySide mailing list
http://lists.qt-project.org/mailman/listinfo/pyside
David García Garzón
2012-08-28 12:48:32 UTC
Permalink
Post by Hugo Parente Lima
Post by David García Garzón
Sorry for the previous unfinished message. Here goes the final one.
I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.
Does anyone know how recover the C++ QObject from the PyObject in PySide?
Shiboken::Object::cppPointer(...), it's on libshiboken basewrapper.h
It receives two parameters, a SbkObject* and a PyTypeObject*, the SbkObject*
will be your PyObject*, just cast it and make sure it always will be a
Python object representing a C++ object bound using Shiboken, the
Shiboken::TypeResolver::get("QObject*")->pythonType();
TypeResolver class is located on libshiboken typeresolver.h header.
Hope this would help you.
Yes, thanks, this seems to be just what i needed. You even provided answer to
what i wanted to ask next, how to identify pyside objects. No time to try it
just now but i am eager to try it to see if it works. Thanks a lot.
David
Hugo Parente Lima
2012-08-28 14:25:18 UTC
Permalink
Post by David García Garzón
Post by Hugo Parente Lima
Post by David García Garzón
Sorry for the previous unfinished message. Here goes the final one.
I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.
Does anyone know how recover the C++ QObject from the PyObject in PySide?
Shiboken::Object::cppPointer(...), it's on libshiboken basewrapper.h
It receives two parameters, a SbkObject* and a PyTypeObject*, the
SbkObject* will be your PyObject*, just cast it and make sure it always
will be a Python object representing a C++ object bound using Shiboken,
the
Shiboken::TypeResolver::get("QObject*")->pythonType();
TypeResolver class is located on libshiboken typeresolver.h header.
Hope this would help you.
Yes, thanks, this seems to be just what i needed. You even provided answer
to what i wanted to ask next, how to identify pyside objects. No time to
try it just now but i am eager to try it to see if it works. Thanks a lot.
There's a function on basewrapper.h that do just that, test if the PyObject is
a SbkObject, i.e. a PySide object.

Shiboken::Object::checkType(PyObject*)

Returns true if the object is an instance of a type created by the Shiboken
generator.
Post by David García Garzón
David
David García Garzón
2012-08-29 21:48:45 UTC
Permalink
Post by Hugo Parente Lima
Post by David García Garzón
Post by Hugo Parente Lima
Post by David García Garzón
Sorry for the previous unfinished message. Here goes the final one.
I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.
Does anyone know how recover the C++ QObject from the PyObject in PySide?
Shiboken::Object::cppPointer(...), it's on libshiboken basewrapper.h
It receives two parameters, a SbkObject* and a PyTypeObject*, the
SbkObject* will be your PyObject*, just cast it and make sure it always
will be a Python object representing a C++ object bound using Shiboken,
the
Shiboken::TypeResolver::get("QObject*")->pythonType();
TypeResolver class is located on libshiboken typeresolver.h header.
Hope this would help you.
Yes, thanks, this seems to be just what i needed. You even provided answer
to what i wanted to ask next, how to identify pyside objects. No time to
try it just now but i am eager to try it to see if it works. Thanks a lot.
There's a function on basewrapper.h that do just that, test if the PyObject is
a SbkObject, i.e. a PySide object.
Shiboken::Object::checkType(PyObject*)
Returns true if the object is an instance of a type created by the Shiboken
generator.
Post by David García Garzón
David
Thats the final code:

void * shibokenUnwrap(PyObject * pyobject)
{
:...if (not Shiboken::Object::checkType(pyobject))
:...:...return 0; // Not a shiboken object
:...SbkObject * sbkobject = (SbkObject *) pyobject;

:...PyTypeObject * type =
Shiboken::TypeResolver::get("QObject*")->pythonType();
:...void * cppobject = Shiboken::Object::cppPointer(sbkobject, type);
:...if (not cppobject)
:...:...return 0; // Not a QObject
:...return cppobject;
}

I got it compiling, but to get it working i still need do the opposite
way. Converting a new c++ qobject created in c++ into a pyside pyobject.

I found in the headers the promising function
Shiboken::Object::newObject but i don't know what i should send as first
parameters. Any ideas?.

David.
David García Garzón
2012-09-03 01:48:17 UTC
Permalink
Post by Hugo Parente Lima
Post by David García Garzón
Post by Hugo Parente Lima
Post by David García Garzón
Sorry for the previous unfinished message. Here goes the final one.
I am porting a CPython library (boost based indeed) from PyQt to PySide.
I had a function in the library that received a Sip wrapped widget
as a PyObject and I used the very ugly SIP api to recover a pointer to the
actual C++ QObject.
Does anyone know how recover the C++ QObject from the PyObject in PySide?
Shiboken::Object::cppPointer(...), it's on libshiboken basewrapper.h
It receives two parameters, a SbkObject* and a PyTypeObject*, the
SbkObject* will be your PyObject*, just cast it and make sure it always
will be a Python object representing a C++ object bound using Shiboken,
the
Shiboken::TypeResolver::get("QObject*")->pythonType();
TypeResolver class is located on libshiboken typeresolver.h header.
Hope this would help you.
Yes, thanks, this seems to be just what i needed. You even provided answer
to what i wanted to ask next, how to identify pyside objects. No time to
try it just now but i am eager to try it to see if it works. Thanks a lot.
There's a function on basewrapper.h that do just that, test if the PyObject is
a SbkObject, i.e. a PySide object.
Shiboken::Object::checkType(PyObject*)
Returns true if the object is an instance of a type created by the Shiboken
generator.
Thanks for all the help. Here it is the final working code, so people
following this thread in the future can take it:

void * shibokenUnwrap(PyObject * pyobject)
{
if (not Shiboken::Object::checkType(pyobject))
return error("Not a shiboken object");

SbkObject * sbkobject = (SbkObject *) pyobject;

PyTypeObject * type = Shiboken::SbkType<QObject>();

void * cppobject = Shiboken::Object::cppPointer(sbkobject, type);
if (not cppobject)
return error("Not a QObject");

return cppobject;
}


Notice, that I had to change the proposed line to get the type because
it crashed:
PyTypeObject* type =
Shiboken::TypeResolver::get("QObject*")->pythonType();
instead, i wrote:
PyTypeObject * type = Shiboken::SbkType<QObject>();


I also found a high level function to do the wrapping:

PyObject * shibokenWrap(QObject * qobject)
{
return Shiboken::createWrapper(qobject, /*python owns*/ false);
}


Let me launch one more question: Now, besides imports, i almost have the
same user code for PyQt[1] and PySide[2]... but a function
loadUi(uifile) which has to choose which wrapper to use to return the
loaded widget to python. I had to provide a different
loadUiPySide(uifile) which wraps using shiboken instead.

But i would like a user code transparent solution, so, is there any way
to know which of the two frameworks is being used? from c++ (better),
from the python library (also good) but not from the user python code.


David.

[1] http://clam-project.org/clam/trunk/ipyclam/demo_ipyclam_pyqt_sms
[2] http://clam-project.org/clam/trunk/ipyclam/demo_ipyclam_pyside_sms
Loading...