Creating Python Bindings to LabPlot's C++ Backend
GSoC '24 KDE Blog Post #2
Welcome back! This blog post is a follow-up to my previous one titled: "Improving Python Interoperability with LabPlot". You can give it a read for more context, but as a summary, I previously outlined two tasks which I aim to complete to make LabPlot a more "Python-friendly" application. This blog post goes into details on the first task: "Creating Python bindings to LabPlot's C++ backend".
Overview of LabPlot's Design
LabPlot is a Qt-based C++ application and its codebase is structured as a frontend which the user interacts with and a backend which does the data analysis and visualisation heavy lifting. The backend provides the core functionalities and the frontend calls the backend in response to the users interactions. The purpose of this task is to make the C++ backend usable from a Qt-based Python program. But how?
CPython Extension Modules
Thankfully, CPython plays nicely with C/C++ by allowing Python code call C/C++ code using "CPython Extension Modules". In other words, by adding some CPython glue code to the existing LabPlot C++ backend code, I can compile and import the output library from Python to access the LabPlot functionality exported by the CPython Extension Modules.
Python Binding Generators
Fortunately, there are tools that can generate the CPython glue code needed to create a "CPython Extension Module". Usually, these tools are helpful for large projects with many types. Example tools are the widely known Boost.Python, pybind11 and the lesser known shiboken.
Shiboken
Shiboken was chosen as the binding generator for LabPlot because it was built primarily for generating Python bindings for Qt and LabPlot is Qt-based. Shiboken is tried and test, it is used to generate the official Qt Python bindings (pyside) and is maintained by the Qt Company.
Most of the CPython glue code in a CPython Extension Module is for converting between C++ and Python types and for handling polymorphic types. Since shiboken is used to generate the official Qt Python bindings (pyside), all the work needed for converting between Qt and Python types has already been done by the Qt Company. I then need to focus only on any LabPlot specific types.
Using Shiboken
Following this guide, I was able to setup a CMake build for shiboken to generate the Python bindings for LabPlot's C++ backend. It was much easier than expected, I only had to tell shiboken what C++ types to generate Python bindings for and it did it's magic.
Well, onto the next.