How to pass a python PyQt6 object to C++

June 27, 2025

PyQt6 does not bind several functions... but they are all accessible via C++ so how do you pass a PyQt6 object to c++?

Fortunately it's quite simple, simply use sip to unwrap the instance and get the pointer and cast it.

namespace py = pybind11;

template<typename T>
T* unwrap_pyqt6(py::object w, const char* module, const char* attr)
{
    py::object mod = py::module_::import(module);
    py::type cls = mod.attr(attr);
    if (!py::isinstance(w, cls)) {
        throw py::type_error("Cannot unwrap pyqt object");
    }
    py::object sip = py::module_::import("PyQt6.sip");
    py::object unwrapinstance = sip.attr("unwrapinstance");
    py::int_ addr = unwrapinstance(w);
    return reinterpret_cast<T*>(PyLong_AsVoidPtr(addr.ptr()));
}

Then pass the c++ type and the corresponding python types (as a sanity check).

QOpenGLWidget* widget = unwrap_pyqt6<QOpenGLWidget>(w, "PyQt6.QtOpenGLWidgets", "QOpenGLWidget");