KDAB / cxx-qt

Safe interop between Rust and Qt
https://kdab.github.io/cxx-qt/book/
1.08k stars 76 forks source link

how does full_cargo_build help rust coders to interface with qt #228

Closed omac777 closed 1 year ago

omac777 commented 2 years ago

After reading the code commit for: https://github.com/KDAB/cxx-qt/pull/221/commits/5764febb37e07143f8f398c85e813e75ee30d9fe#diff-8bb0fb2647a33c2605f3991d38e6bbc236494370f8300f7bec63b03e182c3f31

When I heard there would be a full cargo build, I envisioned the rust main driver would:

In the actual code commit however:

The only rust functions I saw were gluing some qml functions to rust callback functions. The majority of the code was still cpp in this example. This example feels as though it's more to accommodate c++ coders rather than rust coders. It begs the question which audience of coders are you trying to reach and encourage qt adoption with this example? The c++ coders or the rust coders? I'll admit this example helps rust coders to compile C++ code from within the cargo tool, yes that's helpful.

It's not what I expect to see to encourage rust users to adopt qt for building guis. I appreciate all the effort made here, but please understand it from a rust user's perspective that when we adopt Rust, ideally we ultimately wish to minimize if not entirely abandon the use of C++, yet still manage to successfully use Qt to build guis somehow.

I truly believe the approach used by rust-qt to be more rust-friendly: https://github.com/rust-qt/examples/tree/master/widgets/todo_list The example highlights:

Thank you for listening.

Be-ing commented 2 years ago

Hi, thanks for the feedback. Indeed, the example doesn't have a lot of Rust code, but it's just that, an example. You can add as much Rust code as you want. The important point is that little C++ shim for launching the QQmlApplicationEngine is all the C++ you need; everything else can be done in Rust + QML. I agree that adding more Rust code would illustrate this point better. In #221 I was only focused on figuring out how to get it to build with Cargo, so I didn't focus on making the Rust code do anything particularly interesting. However, I have thought about turning the example into a little audio player using the creek and cpal crates.

Be-ing commented 2 years ago

To clarify, cxx-qt is completely separate from rust-qt. rust-qt uses ritual to autogenerate unsafe Rust bindings to Qt's C++ API. rust-qt is also not actively developed anymore. By contrast, cxx-qt uses cxx to generate safe bidirectional Rust <--> C++ bindings. As described in the project announcement blog post, the initial motivation for cxx-qt was to integrate Rust into existing C++ applications. rust-qt as well as qmetaobject only allow calling Qt from Rust, but not using Rust from C++. However, since #221 has been merged, it is practical to use cxx-qt in primarily Rust applications as well. This makes it feasible to gradually rewrite existing C++ applications into Rust piece by piece and eventually get rid of the C++ build system.

Be-ing commented 2 years ago

there are no C++ modules within the todo_list project itself, but heavily relies on Rust crates hiding all that complexity/bridging. I still don't understand why KDAB disagrees with this approach and as of yet not embraced it nor integrated some of it with its own approach. Please enlighten me.

The reason is that we don't have bindings for QGuiApplication, QQmlApplicationEngine, and qmlRegisterType. Unlike rust-qt with ritual, our bindings to Qt are not entirely automated. The cxx-qt-lib crate in this repository uses cxx to bind common classes from QtCore and QtGui, which requires manually implementing some code. So at this point we only have bindings to a handful of Qt classes. A developer at Google is working on autocxx to automate generating cxx bindings, but that project is still in early development and we haven't tried using it yet. However, considering how little C++ code is required to build a functioning QML application with Cargo, I'm not particularly motivated to prioritize adding bindings for those few missing pieces above other work on our roadmap. Also, applications might want to add a little of their own C++ code in a primarily Rust application and the current setup facilitates that easily.

ahayzen-kdab commented 2 years ago

I think there are a few things to note here, we as CXX-Qt i think have the following beliefs

  1. To use Qt you need to have knowledge of it's Qt C++ API (whether that is with Widgets or QML)
  2. Qt's API is "unsafe" from the perspective of Rust and would require large amounts of wrapping to make safe
  3. Creating one to one bindings would result in an unsafe API where you are just writing C++ code but in Rust
  4. We believe that QML and Widgets are still powerful for writing GUIs and Rust is most useful in the business logic/model layers
  5. If you want to write something from scratch in pure Rust, something like Slint ( https://github.com/slint-ui/slint ) or egui or iced etc are likely a better choice long term

These are just i think our beliefs and philosophy for the project, we aren't saying others are wrong though. Eg qmetaobject-rs is trying to do 2) here and ritual's bindings are 3). They are useful for certain usecases.

The primary usecase that we see CXX-Qt being used is for an existing Qt C++ application that wants to "oxidize" to add Rust to parts of the backend, eg moving a C++ module to Rust to parse an unsafe input or use threading etc. This is where being able to add CXX-Qt to the Qt CMake workflow and use it as a QObject/model for QML or Widgets is very powerful.

Being able to have Rust be the main function and not using CMake but cargo has other uses as developers start migrating their Qt C++ apps to using more Rust code. Eg async runtimes might want control over the main function to manage the thread pools etc. Also this allows the developer to get closer to having a larger Rust stack.

But for general things like setting up your QGuiApplication etc, we don't have bindings for those yet. Instead you can either write those in C++ or create your own bindings with CXX/extern blocks or use something like ritual to access the API. (maybe there will be something later we'll see...)

The only rust functions I saw were gluing some qml functions to rust callback functions. The majority of the code was still cpp in this example. This example feels as though it's more to accommodate c++ coders rather than rust coders. It begs the question which audience of coders are you trying to reach and encourage qt adoption with this example? The c++ coders or the rust coders? I'll admit this example helps rust coders to compile C++ code from within the cargo tool, yes that's helpful.

Mostly I think C++ coders who have Qt applications who want to explore Rust, as stated in 1) above if you are using Qt you need knowledge of how C++ works. Trying to hide that in Rust is tricky, instead if you are a Rust-only developer writing from scratch something like Slint may be a better option.

It's not what I expect to see to encourage rust users to adopt qt for building guis. I appreciate all the effort made here, but please understand it from a rust user's perspective that when we adopt Rust, ideally we ultimately wish to minimize if not entirely abandon the use of C++, yet still manage to successfully use Qt to build guis somehow.

I don't personally think abandoning C++ in a single step is viable for most large Qt C++ codebases, they need a slow a gradual conversion of things to Rust. And for now if you are a Rust developer trying to use no C++ then something like Slint is a better option. (as using Qt is always going to have C++ somewhere even if behind the scenes in Qt itself...).

But as things evolve and the base of CXX-Qt is improved maybe it'll become viable to remove larger parts of the C++ code and only use Rust code making it more useful for Rust-only devs, we'll see :-)

Be-ing commented 2 years ago

If you don't have prior experience with C++ and Qt, using cxx-qt for your Rust application is likely not the best option and you'd likely be better off using a Rust GUI library. I am using Slint in another project (my own project, not affiliated with KDAB).

ahayzen-kdab commented 1 year ago

The Cargo / Rust example now does not have any C++ code for the developer to get a QML app running https://github.com/KDAB/cxx-qt/blob/1ca34cf22dca049e5f4af940acf080aa5815533b/examples/cargo_without_cmake/src/main.rs#L15 . This shows how it is possible to write such an app in Rust without C++, but our main focus is still for people who have prior experience of C++ and Qt.

As the example now does not have C++ code and is showing how Rust coders can interface I'm going to close this issue, please open new issues for further or different discussions.