KDE Review: Rust Qt Binding Generator

Jos van den Oever jos at vandenoever.info
Sun Sep 3 17:14:49 BST 2017


Dear KDE-ers,

A new project is up for review: Rust Qt Binding Generator.

The project is a command-line executable that creates Rust code and Qt code 
from a binding description in JSON.

The code is currently at kde:scratch/vandenoever/rust_qt_binding_generator

If you want to use Rust code in your Qt project or if you would like to add a 
Qt UI on your Rust code, this program will help you.

The binding can describe a Objects, Lists and Trees. Objects generate C
++ derived from QObject. Lists and Trees generate C++ classes derived from 
QAbstractItemModel. On the Rust side, a trait is created. This trait is the 
interface that the developer needs to fill with code.

The project comes with a demo application that shows Rust code powering a Qt 
widgets project, a Qt Quick Controls project and a Qt Quick Controls 2 
project. It shows a list, file system tree, a system process view and a chart.

That demo with the code for it is easiest way to appreciate what you can do 
with rust_qt_binding_generator.

The idea of this binding generator is that you write each part in the most 
appropriate language. Rust bindings for Qt are hard to get right and will 
still have caveats for a while. With this generator, you write the UI in C++ 
or QML. The generated code has no dependencies apart from Qt Core and the Rust 
crate libc.

A simple example: Hello World.

```json
{
    "cppFile": "src/greeting.cpp",
    "rust": {
        "dir": "rust",
        "interfaceModule": "interface",
        "implementationModule": "implementation"
    },
    "objects": {
        "Greeting": {
            "type": "Object",
            "properties": {
                "message": {
                    "type": "QString"
                }
            }
        }
    }
}
```

Preparation: create a new CMake project with a Rust project in the folder 
'rust'.

```
kwrite CMakeLists.txt
kwrite bindings.json
mkdir rust
(cd rust && cargo init --name rust --lib)
```

Create bindings with this command:

```bash
rust_qt_binding_generator binding.json
```

Add the files to the main Rust library module, `rust/src/lib.rs`

```rust
extern crate libc;

pub mod interface;
mod implementation;
```

And modify tell Cargo to build a static library in `rust/Cargo.tom`:

```
[package]
name = "rust"
version = "1.0.0"

[dependencies]
libc = "*"

[lib]
name = "rust"
crate-type = ["staticlib"]
```

Next step: put your code in rust/src/implementation.rs:

```rust
use interface::*;

pub struct Greeting {
    emit: GreetingEmitter,
}

impl GreetingTrait for Greeting {
    fn create(emit: GreetingEmitter) -> Greeting {
        Greeting {
            emit: emit,
        }
    }
    fn emit(&self) -> &GreetingEmitter {
        &self.emit
    }
    fn message(&self) -> &str {
        "Hello world!"
    }
}

```

The GreetingEmitter is generated struct that can emit signals such as 
valueChanged(). It is not needed in this simple example, but the interface 
requires it. You might have new values coming in of which you'd need to notify 
the UI.

The demo has more advanced examples. List and Tree let you implement 
QAbstractItemModel with Rust code but the API is quite different.

There is no QAbstractItemModel::data and QAbstractItemModel::setData to 
implement. Instead, you define properties for each list or tree item and have 
to implement functions like

```rust
    fn name(row: usize) -> &str {
        if row == 0 {
            return "Alice";
        }
        "Bob"
    }
```

This project is not a typical C++ KDE project, but I hope it can be part of 
KDE anyway.

Best regards,
Jos



-------------- next part --------------
A non-text attachment was scrubbed...
Name: demo.png
Type: image/png
Size: 37270 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20170903/3f6faaff/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: demo2.png
Type: image/png
Size: 66955 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20170903/3f6faaff/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: demo3.png
Type: image/png
Size: 35390 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20170903/3f6faaff/attachment-0002.png>


More information about the kde-core-devel mailing list