Advertisement
shyamnath

Untitled

May 26th, 2025
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.53 KB | None | 0 0
  1. void PySideAutoQmlBridgePrivate::registerProperties()
  2. {
  3.     Shiboken::AutoDecRef klass(PyObject_Type(m_backend));
  4.     if (!klass) {
  5.         PyErr_Clear();
  6.         return;
  7.     }
  8.  
  9.     // fetch all the class attributes
  10.     Shiboken::AutoDecRef dirList(PyObject_Dir(klass.object()));
  11.     if (!dirList) {
  12.         PyErr_Clear();
  13.         return;
  14.     }
  15.  
  16.     const Py_ssize_t count = PyList_Size(dirList.object());
  17.  
  18.     // find all the properties
  19.     for (Py_ssize_t i = 0; i < count; ++i) {
  20.         PyObject *nameObj = PyList_GetItem(dirList.object(), i);
  21.         if (!PyUnicode_Check(nameObj))
  22.             continue;
  23.  
  24.         QByteArray attrName = Shiboken::String::toCString(nameObj);
  25.  
  26.         Shiboken::AutoDecRef classDescriptor(PyObject_GetAttrString(klass.object(), attrName.constData()));
  27.         if (!classDescriptor)
  28.             continue;
  29.  
  30.         // create a PySideProperty for the property and assign its getter, setter and notify signalb
  31.         // fields
  32.         if (PyObject_TypeCheck(classDescriptor.object(), &PyProperty_Type)) {
  33.             Shiboken::AutoDecRef kwds(PyDict_New());
  34.             if (!kwds) {
  35.                 PyErr_Print();
  36.                 continue;
  37.             }
  38.  
  39.             Shiboken::AutoDecRef getter(PyObject_GetAttrString(classDescriptor.object(), "fget"));
  40.             Shiboken::AutoDecRef setter(PyObject_GetAttrString(classDescriptor.object(), "fset"));
  41.  
  42.             // Create the bound method by binding getter/setter to the instance
  43.             if (!getter.isNull()) {
  44.                 Shiboken::AutoDecRef boundGetter(PyObject_CallMethod(
  45.                     reinterpret_cast<PyObject *>(getter.object()), "__get__", "OO", m_backend, Py_None));
  46.                 PyDict_SetItemString(kwds.object(), "fget", boundGetter.object());
  47.             }
  48.  
  49.             // only add setter if it is implemented
  50.             if (!setter.isNull() && setter.object() != Py_None) {
  51.                 Shiboken::AutoDecRef boundSetter(PyObject_CallMethod(
  52.                     reinterpret_cast<PyObject *>(setter.object()), "__get__", "OO", m_backend, Py_None));
  53.                 PyDict_SetItemString(kwds.object(), "fset", boundSetter.object());
  54.             }
  55.  
  56.             const char* type_name = "QVariant";
  57.             Shiboken::AutoDecRef pyPropertyType(PyUnicode_FromString(type_name));
  58.             PyDict_SetItemString(kwds.object(), "type", pyPropertyType.object());
  59.  
  60.             // TODO: Handle type annotations conversion from Python type to Qt type
  61.             // if (!getter.isNull()) {
  62.             //     Shiboken::AutoDecRef annotations(PyObject_GetAttrString(getter.object(),
  63.             //                                                             "__annotations__"));
  64.             //     if (!annotations.isNull()) {
  65.             //         Shiboken::AutoDecRef return_type(PyDict_GetItemString(annotations.object(),
  66.             //                                                               "return"));
  67.             //         if (!return_type.isNull() && PyType_Check(return_type.object())) {
  68.             //             type_name = ((PyTypeObject*)return_type.object())->tp_name;
  69.             //             Shiboken::AutoDecRef pyPropertyType(PyUnicode_FromString(type_name));
  70.             //             PyDict_SetItemString(kwds.object(), "type", pyPropertyType.object());
  71.             //         }
  72.             //     }
  73.             // }
  74.  
  75.             QByteArray signalName = attrName + "Changed";
  76.             int signalId = m_metaObjectBuilder->addSignal(signalName + "()");
  77.  
  78.             if (signalId >= 0) {
  79.                 QMetaMethod signal = m_metaObjectBuilder->update()->method(signalId);
  80.                 const char *signalSignature = signal.methodSignature().constData();
  81.                 Shiboken::AutoDecRef notifySignal(PyUnicode_FromString(signalSignature));
  82.                 PyDict_SetItemString(kwds.object(), "notify", notifySignal.object());
  83.             }
  84.  
  85.             PyObject *args = PyTuple_New(0);
  86.             Shiboken::AutoDecRef pysidePropObj(
  87.                 PyObject_Call(reinterpret_cast<PyObject *>(PySideProperty_TypeF()), args, kwds.object()));
  88.             Py_DECREF(args);
  89.  
  90.             if (!pysidePropObj) {
  91.                 if (PyErr_Occurred()) {
  92.                     PyErr_Print();
  93.                 }
  94.                 qDebug() << "Failed to create PySideProperty for" << attrName;
  95.                 PyErr_Clear();
  96.                 continue;
  97.             }
  98.  
  99.             // Get the property
  100.             auto *property = reinterpret_cast<PySideProperty *>(pysidePropObj.object());
  101.             Py_INCREF(property);  // Increase ref count since we're storing it
  102.  
  103.             property->d->typeName = type_name;
  104.             if (!getter.isNull()) {
  105.                 property->d->fget = getter.object();
  106.                 Py_INCREF(getter.object());  // Increase ref count for getter
  107.             }
  108.             if (!setter.isNull()) {
  109.                 property->d->fset = setter.object();
  110.                 Py_INCREF(setter.object());  // Increase ref count for setter
  111.             }
  112.  
  113.             // Initialize the private data
  114.             if (!property || !property->d) {
  115.                 qDebug() << "Invalid PySideProperty or uninitialized private data for" << attrName;
  116.                 Py_DECREF(property);
  117.                 continue;
  118.             }
  119.  
  120.             int propertyIndex = m_metaObjectBuilder->addProperty(attrName.constData(),
  121.                                                                  pysidePropObj.object());
  122.             m_model->addProperty(propertyIndex, property);
  123.         }
  124.     }
  125. }
  126.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement