-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
MyWxClass to python
I use wxWidgets, wxPython and pybind11.
My project code is here: https://framagit.org/Suryavarman/ma/
and here a video
I have create a class from wxControl.
class M_DLL_EXPORT OgreView : public wxControl
{
public:
OgreView(wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0,
const wxValidator& validator = wxDefaultValidator, const wxString &name=wxPanelNameStr);
[…]
}Here a part of code to export the OgreView to python.
py::class_<API::wx::OgreView>(subModule, "wxOgreView")
.def(py::init<>())
.def(py::init<>
(
[] (py::object inWindow)
{
wxWindow *window = API_Py::wxLoad<wxWindow>(inWindow.release(), "wxWindow");
wxASSERT(window);
return new API::wx::OgreView(window);
}
), py::arg("inWindow")
)
.def("getParentClass", [](const API::wx::OgreView& self){return static_cast<wxControl*>(const_cast<API::wx::OgreView*>(&self));}, py::call_guard<py::gil_scoped_release>(), py::return_value_policy::reference, "Retourne la classe parente de wxOgreView.")
;Here the casters:
wxPy.h
wxPy.tpp
wxPy.cpp
Note: the typed casters are define at the end of wxPy.h file.
M_WX_PY_CASTER(wxWindow, "wx.Window")
M_WX_PY_CASTER_NO_CLASSINFO(wxSize, "wx.Size")
M_WX_PY_CASTER_NO_CLASSINFO(wxPoint, "wx.Point")
M_WX_PY_CASTER(wxValidator, "wx.Validator")
M_WX_PY_CASTER(wxControl, "wx.Control")
M_WX_PY_CASTER(wxAuiNotebook, "wx._aui.AuiNotebook")
M_WX_PY_CASTER(wxFrame, "wx.Frame")I want to remove the getParentClass to use directly OgreView parent class.
To do that there are two options (see pybind11 documentation)
- Load and add the PyObject parent
py::object py_wx_module = py::module::import("wx");
py::object py_type_wxControl = static_cast<py::object>(py_wx_module.attr("Control"));
py::class_<API::wx::OgreView>(subModule, "wxOgreView", py_type_wxControl)
.def(py::init<>
(- Load the wxPython module and let the casters working.
py::object py_wx_module = py::module::import("wx");
py::class_<API::wx::OgreView, wxControl>(subModule, "wxOgreView")
.def(py::init<>
(The both doesn't work.
First option:
- During the loading module, it's crash here (segmentation fault):
pybind11.h > generic_type::initialize(const type_record &rec)
line: 933
else if (rec.bases.size() == 1) {
auto parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());
tinfo->simple_ancestors = parent_tinfo->simple_ancestors; // <--- crash here line 933
}parent_tinfo is null because, get_type_info return a nullptr if the types are not pybind11-registered.
Remark: It will be good to test the parent_tinfo value.
pybnd11/cast.h line 155-167 get_type_info function
// Gets a single pybind11 type info for a python type. Returns nullptr if neither the type nor any
// ancestors are pybind11-registered. Throws an exception if there are multiple bases--use
// `all_type_info` instead if you want to support multiple bases.Second option:
-
During the loading module, pybind11 send this error:
ImportError: generic_type: type "wxOgreView" referenced unknown base type "wxControl"
Questions:
What does it mean exactly «pybind11-registered»? Define the caster is not enough?