The qmetaobject crate is a crate which is used to expose rust object to Qt and QML.
- Rust procedural macro (custom derive) to generate a QMetaObject at compile time.
- Bindings for the main Qt types using the cpp! macro from the cpp crate.
- Users of this crate should not require to type any line of C++ or use another build system than cargo.
- Performance: Avoid any unnecessary conversion or heap allocation.
Presentation Blog Post: https://woboq.com/blog/qmetaobject-from-rust.html
extern crate qmetaobject;
use qmetaobject::*;
#[macro_use] extern crate cstr;
#[derive(QObject,Default)]
struct Greeter {
base : qt_base_class!(trait QObject),
name : qt_property!(QString; NOTIFY name_changed),
name_changed : qt_signal!(),
compute_greetings : qt_method!(fn compute_greetings(&self, verb : String) -> QString {
return (verb + " " + &self.name.to_string()).into()
})
}
fn main() {
qml_register_type::<Greeter>(cstr!("Greeter"), 1, 0, cstr!("Greeter"));
let mut engine = QmlEngine::new();
engine.load_data(r#"import QtQuick 2.6; import QtQuick.Window 2.0;
import Greeter 1.0
Window {
visible: true;
Greeter { id: greeter; name: 'World'; }
Text { anchors.centerIn: parent; text: greeter.compute_greetings('hello'); }
}"#.into());
engine.exec();
}
- Create object inheriting from QObject, QQuickItem, QAbstractListModel, QQmlExtensionPlugin, ...
- Export Qt properties, signals, methods, ...
- Also support
#[derive(QGadget)]
(same as Q_GADGET) - Create Qt plugin (see examples/qmlextensionplugins)
- Partial scene graph support
Requires Qt >= 5.8
It is quite likely that you would like to call a particular Qt function wich is not wrapped by this crate.
In this case, it is always possible to access C++ directly from your rust code using the cpp! macro.
Example: from examples/graph/src/main.rs
, the struct Graph is a QObject deriving from QQuickItem,
QQuickItem::setFlag is currently not exposed in the API but we wish to call it anyway.
impl Graph {
fn appendSample(&mut self, value: f64) {
// ...
let obj = self.get_cpp_object();
cpp!(unsafe [obj as "QQuickItem*"] { obj->setFlag(QQuickItem::ItemHasContents); });
// ...
}
}
But ideally, we should wrap as much as possible so this would not be needed. You can request API as a github issue, or contribute via a pull request.