-1

Can I write custom Qt widget in pure C++, compile it and use in PyQt5 using pybind11 binding library? If possible, how difficult will it be to implement it using pybind11 ?

I know this is possible using sip library (custom C++ Qt widget <--sip--> PyQt5). But I would like to do it using pybind11 as I use it already in my project and I am more comfortable with c++.

3
  • Well, if you're able to directly access widgets as memory addresses, you could use sip to expose them as real PyQt objects, if you don't do that it will not work, since PyQt expects sip objects, not anything that "wraps" a Qt object, that's why PyQt and PySide cannot be used together, even if they are using the same Qt binaries. Commented Sep 26, 2023 at 13:08
  • I don't know the reasons of who voted, but it may be related to the fact that you could have considered some testing (even if unsuccessful) showing us its results, which should count as much as "research effort", a minimum requirement for every question, which in your case is a bit limited, except for the fact that you knew that sip exists. In any case, don't think of downvotes as personal accusations or attempts to "target" you as a person. Commented Sep 26, 2023 at 13:27
  • The fact that a question is "legit" doesn't always mean that it meets SO guidelines, and, most importantly, personal opinions about its validity as a SO question. In any case, I have no experience with C++ and the low level implementation of python bindings, but, AFAIK, if you can make an object available on the Python and you can get a shared pointer for it, then interfacing it with PyQt is relatively simple: as long as you have the memory address to the C++ object, you should be able to use sip.wrapinstance(addr, type) to get its PyQt counterpart and use it with other PyQt objects. Commented Sep 26, 2023 at 19:36

1 Answer 1

1

PyQt expects sip objects, so it is not possible to create Python object directly compatible with PyQt5 using pybind11.

But using sip.wrapinstance, it is possible to get a PyQt5 object that is actually bound with pybind11. sip.wrapinstance function is not documented in official SIP doc v6.7. It is hardly documented in the SIP v4 (no longer supported) archive.

To get a proper PyQt5 object from a pybind11 object:

Here is a C++ Visualizer class that is exposed to python using pybind11 and that returns a pointer to a C++ Qt Object:

py::class_<Visualizer>(m, "StreamVisualizer")
    .def(py::init<>(), "Show ")
    .def("get_quick_widget", [](const Visualizer & v)
         { return static_cast<void*>(v->getQuickWidget()); },
         py::return_value_policy::reference)
    ;

To get the PyQt5 QuickWidget handler, use ctypes in order to extract the pointer from the PyCapsule, then, use sip.wrapinstance on the pointer:

import sys
import mypybind11lib
import PyQt5.QtWidgets
import PyQt5.QtCore    
import PyQt5.QtQuickWidgets
# we must load sip module after PyQt5 so that we are sure to load 
# PyQt's sip module of the current PyQt
import sip 
#print(sip) 

import ctypes
def convert_capsule_to_int(pycapsule):
    ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
    ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
    return ctypes.pythonapi.PyCapsule_GetPointer(pycapsule, None)

def convert_to_pyqt(pycapsule, qtype):
    return sip.wrapinstance(convert_capsule_to_int(pycapsule), qtype)


app = PyQt5.QtWidgets.QApplication(sys.argv)
win = PyQt5.QtWidgets.QMainWindow()
win.setFixedSize(400, 300)
    
visualizer = mypybind11lib.Visualizer()
pyQt5QuickWidget = convert_to_pyqt(visualizer.get_quick_widget(), 
                                   PyQt5.QtQuickWidgets.QQuickWidget)
win.setCentralWidget(pyQt5QuickWidget)
win.show()
app.exec_()
Sign up to request clarification or add additional context in comments.

Comments

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.