PySide6 with Python C API: EXC_BAD_ACCESS error when calling a method with inherited class from QRasterWindow
-
Environment:
Python version: 3.9.6 (default, May 7 2023, 23:32:45)
PySide6 version: 6.7.0When 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);
Output:
QRasterWindow.metric value is 0 PCJ value is 436267760 In QRW_init PCJ_inst value is 263891520 mm value is 263896816 uu value is 439183584 ww value is 263877728 zsh: segmentation fault
What is wrong?
-
Hi and welcome to devnet,
Excuse my silly question but why go through the length of using PySide6 using Python C API ? Why not write your application directly in C++ ?
-
Hi and thanks for your welcome.
Good question, I'm trying to create Qt bindings for Ada language.
Some attempts with C++ were failing due to some C++ subtleties.
But Python provides C API which I can used easily with Ada.
I provide some very first Qt bindings for Ada.
But class inheritance is still in Python.
I wanted to make them full Ada. I'm able to instantiate a class inherited from QRasterWindow (for instance) but a call to the method metric (for instance) provoques a seg fault.
(for simplicity I post the code in C)