[C++-sig] No Python class registered and a simple Qt type. Why?

Luiz Vitor Martinez Cardoso grabber at gmail.com
Mon Oct 1 04:26:23 CEST 2012


Dear,

I'm trying to integrate a simple Qt/C++ and Python... but I'm getting
"*TypeError:
No Python class registered for C++ class QString*" error message and I
can't realize why.

I already have read dozen of posts on mailing lists and Google search
results... but I can't figure out the solution in my brain. Could someone
help me?

I'm attaching all the relevante code I use. Read it from last to the
beginning =]

*Boost.Python converters*
*
*

> #ifndef QTTOPYOBJECTS_H
> #define QTTOPYOBJECTS_H
> #include "faceobject.h"
> #include <boost/python.hpp>
> using namespace boost::python;
> // C = QList<T>
> template <class C>
> struct QList_to_python_list
> {
>   typedef typename C::value_type T;
>   typedef typename C::const_iterator iter;
>   static PyObject* convert(C const &list)
>   {
>     // the python list
>     boost::python::list pyList;
>     foreach (const T& item, list) {
>       pyList.append(item);
>     }
>     return incref(pyList.ptr());
>   }
> };
> // C = QList<T*>
> template <class C>
> struct QList_ptr_to_python_list
> {
>   typedef typename C::value_type T;
>   typedef typename C::const_iterator iter;
>   static PyObject* convert(C const &list)
>   {
>     // the python list
>     boost::python::list pyList;
>     // we need to wrap the pointers into PyObjects
>     typename boost::python::reference_existing_object::apply<T*>::type
> converter;
>     for (iter i = list.begin(); i != list.end(); ++i) {
>       PyObject *obj = converter(*i);
>       object real_obj = object(handle<>(obj));
>       // append the PyObject
>       pyList.append(real_obj);
>     }
>     return incref(pyList.ptr());
>   }
> };
> template <class C>
> struct QList_ptr_from_python_list
> {
>   typedef typename C::value_type T;
>   QList_ptr_from_python_list()
>   {
>     converter::registry::push_back( &convertible, &construct, type_id<C>()
> );
>   }
>   static void* convertible(PyObject *obj_ptr)
>   {
>     //is this a tuple type?
>     if (PyTuple_Check(obj_ptr)) {
>       //check the tuple elements... - convert to a boost::tuple object
>       boost::python::tuple t( handle<>(borrowed(obj_ptr)) );
>       //how many elements are there?
>       int n = PyTuple_Size(obj_ptr);
>       //can they all be converted to type 'T'?
>       for (int i=0; i<n; ++i) {
>         if (!boost::python::extract<T>(t[i]).check())
>           return 0;
>       }
>       //the tuple is ok!
>       return obj_ptr;
>     }
>     //is this a list type?
>     else if (PyList_Check(obj_ptr)) {
>       //check that all of the list elements can be converted to the right
> type
>       boost::python::list l( handle<>(borrowed(obj_ptr)) );
>       //how many elements are there?
>       int n = PyList_Size(obj_ptr);
>       //can all of the elements be converted to type 'T'?
>       for (int i=0; i<n; ++i) {
>         if (!boost::python::extract<T>(l[i]).check())
>           return 0;
>       }
>       //the list is ok!
>       return obj_ptr;
>     }
>     //could not recognise the type...
>     return 0;
>   }
>   static void construct(PyObject *obj_ptr,
> converter::rvalue_from_python_stage1_data *data)
>   {
>     if (PyTuple_Check(obj_ptr)) {
>       //convert the PyObject to a boost::python::object
>       boost::python::tuple t( handle<>(borrowed(obj_ptr)) );
>       //locate the storage space for the result
>       void* storage =
> ((converter::rvalue_from_python_storage<C>*)data)->storage.bytes;
>       //create the T container
>       new (storage) C();
>       C *container = static_cast<C*>(storage);
>       //add all of the elements from the tuple - get the number of
> elements in the tuple
>       int n = PyTuple_Size(obj_ptr);
>       for (int i=0; i<n; ++i)
>         container->append( extract<T>(t[i])() );
>       data->convertible = storage;
>     }
>     else if (PyList_Check(obj_ptr)) {
>       //convert the PyObject to a boost::python::object
>       boost::python::list l( handle<>(borrowed(obj_ptr)) );
>       //locate the storage space for the result
>       void* storage =
> ((converter::rvalue_from_python_storage<C>*)data)->storage.bytes;
>       //create the T container
>       new (storage) C();
>       C *container = static_cast<C*>(storage);
>       //add all of the elements from the tuple - get the number of
> elements in the tuple
>       int n = PyList_Size(obj_ptr);
>       for (int i=0; i<n; ++i)
>         container->append( extract<T>(l[i])() );
>       data->convertible = storage;
>     }
>   }
> };
> struct QString_to_python_str
> {
>   // FIXME: handle this using boost::python::str
>   static PyObject* convert(QString const &str)
>   {
> #if defined ( Py_UNICODE_WIDE )
>     PyObject *obj = PyUnicode_FromUnicode( 0, str.length() );
>     if (!obj)
>       throw_error_already_set();
>     Py_UNICODE *pyu = PyUnicode_AS_UNICODE( obj );
>     for (int i = 0; i < str.length(); ++i)
>       *pyu++ = (str.at(i)).unicode();
>     return obj;
> #else
>    return PyUnicode_FromWideChar( (const wchar_t*) str.unicode(),
> str.length() );
> #endif
>   }
> };
> struct QString_from_python_str
> {
>   QString_from_python_str()
>   {
>     converter::registry::push_back( &convertible, &construct,
> type_id<QString>() );
>   }
>   static void* convertible(PyObject *obj_ptr)
>   {
>     if (PyUnicode_Check(obj_ptr))
>       return obj_ptr;
>     if (PyString_Check(obj_ptr))
>       return obj_ptr;
>     return 0;
>   }
>   static void construct(PyObject *obj_ptr,
> converter::rvalue_from_python_stage1_data *data)
>   {
>     if (PyUnicode_Check(obj_ptr)) {
>       void *storage = ((converter::rvalue_from_python_storage<QString> *)
> data)->storage.bytes;
>       PY_UNICODE_TYPE *ucode = PyUnicode_AS_UNICODE(obj_ptr);
>       int len = PyUnicode_GET_SIZE(obj_ptr);
> #if defined(Py_UNICODE_WIDE)
>       QString* out = new(storage) QString;
>       for ( int i = 0; i < len; ++i )
>         out->append( (uint)ucode[i] );
> #else
>       new(storage) QString( (const QChar *)ucode, len );
> #endif
>       data->convertible = storage;
>     } else if ( PyString_Check( obj_ptr ) ) {
>       const char *value = PyString_AsString(obj_ptr);
>       if(!value)
>         throw_error_already_set();
>       void *storage = ((converter::rvalue_from_python_storage<QString> *)
> data)->storage.bytes;
>       new(storage) QString(QByteArray(value, PyString_Size(obj_ptr)));
>       data->convertible = storage;
>     }
>   }
> };
> template <class C>
> struct QList_from_python_list
> {
>   typedef typename C::value_type T;
>   QList_from_python_list()
>   {
>     converter::registry::push_back( &convertible, &construct, type_id<C>()
> );
>   }
>   static void* convertible(PyObject *obj_ptr)
>   {
>     //is this a tuple type?
>     if (PyTuple_Check(obj_ptr)) {
>       //check the tuple elements... - convert to a boost::tuple object
>       boost::python::tuple t( handle<>(borrowed(obj_ptr)) );
>       //how many elements are there?
>       int n = PyTuple_Size(obj_ptr);
>       //can they all be converted to type 'T'?
>       for (int i=0; i<n; ++i) {
>         if (!boost::python::extract<T>(t[i]).check())
>           return 0;
>       }
>       //the tuple is ok!
>       return obj_ptr;
>     }
>     //is this a list type?
>     else if (PyList_Check(obj_ptr)) {
>       //check that all of the list elements can be converted to the right
> type
>       boost::python::list l( handle<>(borrowed(obj_ptr)) );
>       //how many elements are there?
>       int n = PyList_Size(obj_ptr);
>       //can all of the elements be converted to type 'T'?
>       for (int i=0; i<n; ++i) {
>         if (!boost::python::extract<T>(l[i]).check())
>           return 0;
>       }
>       //the list is ok!
>       return obj_ptr;
>     }
>     //could not recognise the type...
>     return 0;
>   }
>   static void construct(PyObject *obj_ptr,
> converter::rvalue_from_python_stage1_data *data)
>   {
>     if (PyTuple_Check(obj_ptr)) {
>       //convert the PyObject to a boost::python::object
>       boost::python::tuple t( handle<>(borrowed(obj_ptr)) );
>       //locate the storage space for the result
>       void* storage =
> ((converter::rvalue_from_python_storage<C>*)data)->storage.bytes;
>       //create the T container
>       new (storage) C();
>       C *container = static_cast<C*>(storage);
>       //add all of the elements from the tuple - get the number of
> elements in the tuple
>       int n = PyTuple_Size(obj_ptr);
>       for (int i=0; i<n; ++i)
>         container->append( extract<T>(t[i])() );
>       data->convertible = storage;
>     }
>     else if (PyList_Check(obj_ptr)) {
>       //convert the PyObject to a boost::python::object
>       boost::python::list l( handle<>(borrowed(obj_ptr)) );
>       //locate the storage space for the result
>       void* storage =
> ((converter::rvalue_from_python_storage<C>*)data)->storage.bytes;
>       //create the T container
>       new (storage) C();
>       C *container = static_cast<C*>(storage);
>       //add all of the elements from the tuple - get the number of
> elements in the tuple
>       int n = PyList_Size(obj_ptr);
>       for (int i=0; i<n; ++i)
>         container->append( extract<T>(l[i])() );
>       data->convertible = storage;
>     }
>   }
> };
>


> void export_QList()
> {
>     to_python_converter< QList<QString>, QList_ptr_to_python_list<
> QList<QString> > >();
>     QList_ptr_from_python_list< QList<QString> >();
> }

void export_QString()
> {
>     to_python_converter< QString, QString_to_python_str >();
>     QString_from_python_str();
> }

#endif // QTTOPYOBJECTS_H



*C++*


> class QListTest
> {
>   public:
>     QList<QString> constantStringList()
>     {
>       QList<QString> list;
>       list.append(QString("test 1"));
>       list.append(QString("test 2"));
>       list.append(QString("test 3"));
>       return list;
>     }
>     const QList<QString>& stringList() const
>     {
>       return m_list;
>     }
>     void setStringList(QList<QString> list)
>     {
>       m_list = list;
>     }
>   private:
>     QList<QString> m_list;
> };
>
> BOOST_PYTHON_MODULE(libfaceparser)
> {
>     export_QString();
>     export_QList();
>     class_<QListTest>("QListTest")
>       .def("constantStringList", &QListTest::constantStringList)
>       .def("stringList", &QListTest::stringList,
> return_value_policy<return_by_value>())
>       .def("setStringList", &QListTest::setStringList)
>     ;
> }



*Python*

import libfaceparser
>
> fp = libfaceparser.QListTest()
> print fp.constantStringList()



*Python Console*

> lmvc at debian:~/Projects/adbox_server/adbox_parser/software/output/debug$
> python faceparser.py
> Traceback (most recent call last):
>   File "faceparser.py", line 7, in <module>
>     print fp.constantStringList()
> TypeError: No Python class registered for C++ class QString


Best regards,
Luiz Vitor.

-- 
Regards,

Luiz Vitor Martinez Cardoso
Celular: (11) 7351-7097 | Skype: grabberbr
engineer student at maua.br
<http://maua.br>intern marketing engineer at geindustrial.com.br
entrepreneur at adboxnetwork.com

"If you wanna be successful, you need total dedication, go for your last
limit, give your best and love your love infinitely!"

"The only limits are the ones you place upon yourself"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20120930/9a9d4c5a/attachment-0001.html>


More information about the Cplusplus-sig mailing list