[PySide] Obtaining QObject from PySide based PyObject (complete)

David García Garzón david.garcia at upf.edu
Mon Sep 3 03:48:17 CEST 2012


On 28/08/12 16:25, Hugo Parente Lima wrote:
> On Tuesday, August 28, 2012 02:48:32 PM David García Garzón wrote:
>> On Monday 27 August 2012 16:23:03 Hugo Parente Lima wrote:
>>> On Monday, August 27, 2012 09:12:27 PM David García Garzón wrote:
>>>> 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.
>> 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





More information about the PySide mailing list