0

Environement:

Python version: 3.9.6 (default, May 7 2023, 23:32:45)

PySide6 version: 6.7.0

When I create an instance of QRasterWindow, calling the metric method is ok:

Py_Initialize();

    PyObject * GUI = PyImport_ImportModule("PySide6.QtGui");
    if(!GUI) {
        printf("\nCould not import PySide6.QtGui module.\n");
        return 0;
    }

    // QApplication
    PyObject* QGA = PyObject_GetAttrString(GUI, "QGuiApplication");
    PyObject * argsqa = PyTuple_New (1);
    PyObject * listqa = PyList_New (1);
    PyList_SetItem (listqa, 0, PyUnicode_FromString (""));
    PyTuple_SetItem (argsqa, 0, listqa);
    PyObject * res = PyObject_CallObject(QGA, argsqa);

    // QRasterWindow
    PyObject* QRW = PyObject_GetAttrString(GUI, "QRasterWindow");
    if(QRW) {

        // Create instance
        PyObject * args = PyTuple_New (0);
        PyObject * QRW_inst = PyObject_CallObject(QRW, args);
             
        // Call metric
        PyObject * mm = PyObject_GetAttrString(QRW_inst, "metric");

        PyObject * uu = PyObject_GetAttrString(GUI, "QPaintDevice");
        PyObject * ww = PyObject_GetAttrString(uu, "PdmWidth");

        PyObject * argsm = PyTuple_New (1);
        PyTuple_SetItem (argsm, 0, ww);
        PyObject * res = PyObject_CallObject(mm, argsm);

        int val = PyLong_AsLong(res);
        printf("\nQRasterWindow.metric value is %d \n", val);

    } else {
        printf("\nCould not get QRW class.\n");
    }

But if I create a class PCJ inherited from QRasterWindow then calling metric method gives segmentation fault EXC_BAD_ACCESS:

    // Create PCJ class inherited from QRasterWindow
    PyType_Slot slots[] = {
        { Py_tp_doc, "PGJ" },
        { Py_tp_base, QRW },
        { Py_tp_init, QRW_init },
        { 0 },
    };
    PyType_Spec spec = { "PCJ", 0, 0,
                          Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, slots };
    PyTypeObject *PCJ = (PyTypeObject *)PyType_FromSpec(&spec);
    printf("\nPCJ value is %d \n", PCJ);

    // Create PCJ instance
    PyObject * argsj = PyTuple_New (0);
    PyObject * PCJ_inst = PyObject_CallObject((PyObject *) PCJ, argsj);
    printf("\nPCJ_inst value is %d \n", PCJ_inst);
         
    // Call metric
    PyObject * mm = PyObject_GetAttrString(PCJ_inst, "metric");
    printf("\nmm value is %d \n", mm);

    PyObject * uu = PyObject_GetAttrString(GUI, "QPaintDevice");
    printf("\nuu value is %d \n", uu);
    PyObject * ww = PyObject_GetAttrString(uu, "PdmWidth");
    printf("\nww value is %d \n", ww);

    PyObject * argsm = PyTuple_New (1);
    PyTuple_SetItem (argsm, 0, ww);
    PyObject * resj = PyObject_CallObject(mm, argsm); // segmentation fault
    printf("\nresj value is %d \n", resj);

    int valj = PyLong_AsLong(resj);
    printf("\nPCJ.metric value is %d \n", valj);

What is wrong?

4
  • sizeof(slots) that is definitely absolutely wrong. It should probably be 0 to just use the size of the base class. Commented Aug 24, 2024 at 22:13
  • Correct, that was an odd try, maybe sizeof(PyObject)? Commented Aug 25, 2024 at 12:01
  • Probably not PyObject - it's pretty likely that the Qt base class is larger than that. Commented Aug 25, 2024 at 23:36
  • Correct, documentation says "If zero, specifies that tp_basicsize should be inherited." (I've modified the original post) Commented Sep 8, 2024 at 9:50

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.