This library enables building modern Qt Quick user interfaces with a Rust backend, without writing any C++ code. It allows you to run QML code and expose Rust types to QML using simple attribute macros.
Main.rs
use qtbridge::{qobject, QApp};
#[derive(Default)]
pub struct Backend {
}
#[qobject(Singleton)]
impl Backend {
#[qslot]
fn say_hello(&self) {
println!("Hello World!")
}
}
fn main() {
QApp::new()
.register::<Backend>()
.load_qml(include_bytes!("qml/Main.qml"))
.run();
}Main.qml
import QtQuick
import QtQuick.Controls
import hello_world
ApplicationWindow {
visible: true
title: qsTr("Minimal QML app")
Button {
anchors.centerIn: parent
text: "Hello World!"
onClicked: Backend.sayHello()
}
}To use this library, you need:
- One of the supported platforms:
- Linux (
x86_64) - Windows (
x64) - macOS (
arm64) - experimental
- Linux (
- Rust and Cargo (stable, version >= 1.87) from rustup.rs
- C++ toolchain (see Qt platform requirements)
- Qt 6
A C++ toolchain and a Qt installation must be present in the system,
and qmake must be in the system PATH. QtBridge currently requires Qt 6.10
or higher.
Qt can be built from source, downloaded from https://download.qt.io/ or installed via your system's package manager.
Most Linux distributions provide a compatible Qt installation through their
system package manager. You need qtbase, qtbase-private, and qtdeclarative
as a baseline for the provided examples, plus any additional
QML modules you intend to use.
On Fedora 43 and 44 the required packages are:
sudo dnf install qt6-qtbase-devel qt6-qtdeclarative-devel
sudo dnf install qt6-qtbase-private-develOn Ubuntu 26.04 and Debian Testing (Forky) the packages are:
sudo apt install -y qt6-base-dev qt6-declarative-dev
sudo apt install -y qt6-base-private-devOn Ubuntu and Debian, the Qt 6 qmake binary is named qmake6 and the QMAKE
environment variable must be set correspondingly:
export QMAKE=qmake6To make this permanent, add it to your ~/.bashrc:
echo 'export QMAKE=qmake6' >> ~/.bashrc
source ~/.bashrcOn Windows, you need to add the binary path of the targeted Qt installation to
PATH. For the default installation of 6.10.1 by the Qt installer you have to
execute the following command. The exact path depends on the targeted installation.
Command Prompt:
set PATH=%PATH%;C:\Qt\6.10.1\msvc2022_64\bin\PowerShell:
$env:PATH += ";C:\Qt\6.10.1\msvc2022_64\bin\"On Linux, you need to add the binary path of the targeted Qt installation to
PATH and the library path to LD_LIBRARY_PATH:
export PATH=/home/john_doe/dev/qt_build/qtbase/bin:$PATH
export LD_LIBRARY_PATH="/home/john_doe/dev/qt_build/lib:$LD_LIBRARY_PATH"On macOS, you need to add the binary path of the targeted Qt installation to
PATH and the library path DYLD_FRAMEWORK_PATH:
export PATH=/Users/john_doe/dev/qt_build/qtbase/bin:$PATH
export DYLD_FRAMEWORK_PATH=/Users/john_doe/dev/qt_build/qtbase/lib:$DYLD_FRAMEWORK_PATHQtBridge has a single crate with all public APIs:
[dependencies]
qtbridge = "*"Running QML code and starting any Qt-based application is generally done through the
[QApp] type.
Rust types that should be used in QML must be annotated with a [qobject]
attribute macro. Within those blocks you can use the [qproperty],
[qslot], and [qsignal] attribute macros to define how the Rust types appear in QML.
The library provides some special traits that enable Rust types to fulfill specific roles; see [special_traits].
All QObjects in Rust (implemented with [qobject]) are held in
Rc<RefCell<_>>. This allows multiple owners to coexist: your Rust code,
the QML engine, and any number of QML components can all hold a reference
to the same object. QML references follow ordinary JavaScript copy semantics.
A Rust object is only borrowed for the duration of a signal, slot or property invocation from QML. Outside of those calls the object is not borrowed, so Rust code can freely take mutable borrows between QML interactions.
RefCell enforces at runtime that only one mutable borrow exists at a time.
QML requires a mutable borrow to invoke a slot or write a property. When an
object enters Rust, its borrow is cached and reused for any further calls on
the same object within that call chain, conforming to a stack-based model.
A panic occurs only if a second independent borrow of the same object is
attempted from a different point in the call chain.
Note: In the preliminary version of this repository, the package dependency is given as a relative path. With the final release, the package dependency can be resolved with cargo and crates.io. Until then you need to adapt the dependency or check out the whole repository.
The classic "Hello World!" example showing the minimal building bricks for a QtBridge application.
A working backend with data displayed in QML.
This example shows how to combine a Qt UI with tokio runtime
in a multithreaded environment using [QmlMethodInvoker].
Port of the C++ Color Palette example to Rust. Shows a moderately complex application using tokio, reqwest, and serde_json, as well as many QML constructs, such as complex and default properties, including nested property structures.
QtBridge builds on CXX to access the required Qt interfaces.
If your project requires mixing Rust and C++ code, using Qt Widgets, or accessing Qt modules that only provide a C++ API, consider using CXX-Qt instead.
Internally, the library relies on Qt concepts such as QObjects, properties, signals and slots, and the Model/View architecture. While these are exposed through a Rust-friendly API, familiarity with these Qt concepts will help you get the most out of building UIs with Qt Quick.
- Streamline API.
- Enable interoperability with CXX-Qt.
- Extend IDE support in particular for VS Code. Enable the QML language server to understand types generated in Rust.
- Reduce the manual steps for installing and linking to Qt.
If you, your employer, or the legal entity you act on behalf of hold commercial license(s) with a Qt Group entity, Qt Bridges constitutes Pre-Release Code under the Qt License/Frame Agreement governing those licenses, and that agreement's terms and conditions relating to Pre-Release Code apply to your use of Qt Bridges as found in this repo. This Qt Bridges repo may provide links or access to third-party libraries or code (collectively "Third-Party Software") to implement various functions. Use or distribution of Third-Party Software is discretionary and in all respects subject to applicable license terms of applicable third-party right holders.
Qt Bridge for Rust is built using the Rust language and SDK, which is maintained by the Rust Foundation.
Qt Bridge for Rust resides on top of Rust and does not modify it in any form. Rust is a trademark of the Rust Foundation. This project is not affiliated with or endorsed by the Rust Foundation.
An application built with Qt Bridge for Rust will include code from other crates. The main dependency is CXX, "Safe interop between Rust and C++", licensed under the Apache Version 2.0 License or MIT license.