Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Connecting C++ Qt widgets and PySide2 ones



  • I want to mix up these two into one QMainWindow with dynamically loaded docker widgets. Is there an official way of doing this?
    From the point, that PySide2 and Qt are using same shared libraries I can assume that in depth of every PySide2 widget lies a native C++ one. If there's no way of integrating them with API, then how can I get the address of PySide2 widget?
    I can pass this address from Python to C++ code, cast it to QWidget, change parent and so on.



  • @tellien said in Connecting C++ Qt widgets and PySide2 ones:

    I can pass this address from Python to C++ code, cast it to QWidget, change parent and so on.

    I don't understand. Either you write a given program in C++ or in Python, no?



  • No, you can use them together: create python interpreter within C++ code and launch scripts via PyRun_StringFlags.
    That way you can mix them, but only if the Qt version and shared libraries are the same.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You'll likely be interested in the Embedding Python part of this blog article.


  • Banned

    @tellien the only reason you would want to do this is perhaps because PySide2 has still not implemented some aspect of Qt5 that you are wanting to use -- is this a correct assumption?

    If no then why use C++ code within your Python application? That is just going to be a constant pain as you move things forward. Yes it can be done but the big questions is why is it being done and is it absolutely necessary.



  • @Denni-0 No, to support extensions/add-ons, which C++ do not know of at a compile time.

    @SGaist That is almost exactly what I'm looking for. Furthermore, what I'm looking for could even be replaced by this approach. Appreciate it!
    Initially, I was looking for a way to expose PySide2 widget to C++ code, but now I know how to expand existing Qt C++ class to PySide2 and allow modules to interact with it as a PySide2 object, that should suffice.
    Would be great If you could give another hint : )

    In case someone will also look for the code:
    https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/scriptableapplication


  • Lifetime Qt Champion

    Do you mean generate Python bindings for your classes ?



  • @SGaist That's the first approach, to generate bindings via Shiboken and make C++ classes available via Python.
    I'm looking for a way to export PySide2 widget to C++ code, e.g.
    Let's assume we have embedded python module :

    PyMethodDef methods_def[] = {
    	{"c_fun", c_func, METH_VARARGS, ""}
    }
    
    PyModuleDef module_def = {
    	PyModuleDef_HEAD_INIT,
    	"mm",
    	nullptr,
    	-1,
    	methods_def,
    	nullptr,
    	nullptr,
    	nullptr,
    	nullptr
    };
    
    PyObject * c_fun(PyObject * self, PyObject *args)
    {
            // Code where you get PyObject * widget_pyo from args
    	QWidget * aws_wgt = reinterpret_cast<QWidget *>( PyLong_AsLong(widget_pyo) ); // Wrong
    	aws_wgt->setWindowsTitle("h4x");
    }
    
    

    And the Python code will look like this:

    from PySide2.QtWidget import QWidget
    import mm
    aws_wgt = QWidget()
    aws_wgt.resize(200, 200)
    aws_wgt.setWindowsTitle("Awesome widget")
    aws_wgt.show()
    mm..c_fun(aws_wgt)
    

    And run it

    PyObject * dict = PyDict_New();
    PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins() );
    PyRun_StringFlags(py_code, Py_file_input, dict, dict, nullptr);
    

  • Lifetime Qt Champion

    I am not aware of such a way currently. I must say I don't see the point this way around. Making an application scriptable through python, sure, but taking actions on QWidget based python objects from C++ extensions seems a bit convoluted. Can you explain a use case for that ?



  • I believe the most cases I can come up with are already covered by Shiboken bindings.
    The only thing that comes in mind is the speed (C++ runs faster, does not require thread state) and the object relationship.
    If we export C++ Qt Object variable to python this object will be owned by python code. We cannot directly manipulate these PySide2 widgets from C++ code, only via signals/slots (with a particular assumption that PySide2 widgets will follow the required behavior).
    For example, if we are not writing python code, and provide this feature to customers/users and it is required that each python widget must be explicitly registered for some C++ controller. We can expect that user will do this but we cannot be sure.
    And the last point is that as I understand, this won't require shiboken since we don't need to generate Python bindings for C++ code, we need the PySide2 objects to open their insides for C++.



  • @tellien
    I'll say one thing: the rule of thumb is that UI will be so "slow" that Python vs C++ speed won't be relevant (even for output, which you do want fast, remember that even if you are PySide2 the actual Qt code running underneath will be the C++ Qt code in libraries, not Python).

    The difference between Python & C++ will be more noticeable in your code which factors enormous numbers into primes, or sorts a billion items, or launches rockets to The Moon, etc. :)



  • That makes sense, but that does not mean we should prefer PySide2 over Qt. I think we should allow users to choose between these two. And I think exporting raw QWidget pointer from PyObject should take place.

    @SGaist From the point that PySide2 is using same symbols as regular C++ Qt applications I think it will not be too convoluted but as simple as returning a pointer with reinterpret_case<QWidget *> (which will be obtained somehow from SbkObject).
    For users it will mean more freedom to choose where and how they want to use Qt classes and making communication between Python and C++ complete so they would have same interface for same objects.


Log in to reply