What does HackerNews think of qmetaobject-rs?

Integrate Qml and Rust by building the QMetaObject at compile time.

Language: Rust

The thing is that Qt is a C++ toolkit written in C++ and meant to be used from C++ with its C++ API.

Especially if we want to use QtWidgets, the API surface is huge. There are a bunch of bindings with different language, but even the ones that are officially supported like PySide will still be second class citizen and awkward to use.

Automated binding generation will never give you idiomatic API in whatever language. And if you want an idiomatic library that wraps Qt, it's going to take a huge amount of work.

Which is why I think restricting to QML makes sense because that's a much smaller API surface. That was the ambition behind my previous crate that exposes QML to rust: https://github.com/woboq/qmetaobject-rs/

But now I've moved on to another GUI project: Slint https://github.com/slint-ui/slint It is implemented in Rust, but from the start aim to expose its API to several programming languages so bindings can be made idiomatic in almost every programming languages.

I wonder what problems from the list apply to another existing and more mature solution: https://github.com/woboq/qmetaobject-rs/
Rust doesn’t support object inheritance (only traits). It also doesn’t have function overloads or default arguments. Qt relies heavily on all of these C++ features; inheritance is fundamental to how Qt works (for example, it is impossible to respond to mouse/keyboard events without subclassing to override virtual methods), and function overloads with default arguments are used everywhere. As a result, it’s a struggle to shoehorn this object model into Rust.

rust-qt[0] doesn’t support inheritance at all, so you can only connect to things in Qt which accept callbacks using slots. It requires `'static` lifetime on those callbacks, so as far as I can tell you are also forced to use `Rc`s whenever you are doing something with a rust-qt object even if you should be able to use a plain reference. The code is auto-generated, so all APIs are `unsafe`, and no function overloads means names are gross because the function signatures must be expressed in the function name (e.g. the `QMessageBox` constructor[1] becomes `QMessageBox::from_icon2_q_string_q_flags_standard_button_q_widget`). This could be improved by using `Option`s for arguments with defaults, but right now this is what it looks like.

qmetaobject-rs[2] has some support for inheritance but as far as I can tell it’s limited to a couple of base types only. It’s also designed around using QML, so it doesn’t actually expose most of the Qt API. As such I don’t have too much experience with it.

I’m unaware of any other usable Rust Qt bindings right now. I currently make things work by using rust-cpp[3] to create C++ subclasses and smuggle events, but this sucks because it also means the objects on the Rust side need to have the Qt API re-exposed manually since AFAIK there isn’t a way to have Rust handle that without using a code generator. (There might be some hackier ways to make this work, or maybe someone with more Rust experience than me knows of something smarter that could happen, but in any case the ergonomics right now are not good for the average developer.)

[0] https://github.com/rust-qt/ritual

[1] https://doc.qt.io/qt-5/qmessagebox.html#QMessageBox-1

[2] https://github.com/woboq/qmetaobject-rs

[3] https://github.com/mystor/rust-cpp

I'm using this to write Qt bindings: https://github.com/woboq/qmetaobject-rs/

> Is it just about convenience so you don't need to bother with putting your C++ code in a different file?

Yes, mostly. I find that having the code in place makes a big difference. I do not like useless levels of indirection and context switches while coding. This way is much better then having to edit three files (the .cpp, the ffi module, and the caller) each time I want to do a call into C++ while making sure they are in sync.