Crate qmetaobject
source · [−]Expand description
This crate implements binding to the Qt API which allow to use QML from a rust application.
Example:
use cstr::cstr;
use qmetaobject::prelude::*;
// The `QObject` custom derive macro allows to expose a class to Qt and QML
#[derive(QObject,Default)]
struct Greeter {
// Specify the base class with the qt_base_class macro
base: qt_base_class!(trait QObject),
// Declare `name` as a property usable from Qt
name: qt_property!(QString; NOTIFY name_changed),
// Declare a signal
name_changed: qt_signal!(),
// And even a slot
compute_greetings: qt_method!(fn compute_greetings(&self, verb: String) -> QString {
format!("{} {}", verb, self.name.to_string()).into()
})
}
fn main() {
// Register the `Greeter` struct to QML
qml_register_type::<Greeter>(cstr!("Greeter"), 1, 0, cstr!("Greeter"));
// Create a QML engine from rust
let mut engine = QmlEngine::new();
// (Here the QML code is inline, but one can also load from a file)
engine.load_data(r#"
import QtQuick 2.6
import QtQuick.Window 2.0
// Import our Rust classes
import Greeter 1.0
Window {
visible: true
// Instantiate the rust struct
Greeter {
id: greeter;
// Set a property
name: "World"
}
Text {
anchors.centerIn: parent
// Call a method
text: greeter.compute_greetings("hello")
}
}
"#.into());
engine.exec();
}
Basic types
The re-exported crate qttypes
contains binding to the most usefull
basic types such as QString
, QVariant
, …
You can also simply use rust type String
, but using QString might avoid unecessary
conversions in some case.
Meta type
In order to be able to use a type in a signal or method parameter, or as a property type, the type need to implement the QMetaType trait. All the method are provided so you can just implement the QMetaType like this:
use qmetaobject::QMetaType;
#[derive(Default, Clone)]
struct MyPoint(u32, u32);
impl QMetaType for MyPoint {};
With that it is also possible to put the type in a QVariant
Object pinning
Once an object that derives from QObject is exposed to C++, it needs to be pinned, and cannot be moved in memory. Also, since the Qt code can be re-entrant, the object must be placed in a RefCell. The QObjectPinned object is used to enforce the pinning.
If you want to keep pointer to reference, you can use QPointer.
Threading
The QML engine only runs in a single thread. And probably all the QObject
s needs to be living
in the Qt thread. But you can use the queued_callback function to
create callback that can be called from any thread and are going to run in the Qt thread.
This can be done like so:
use qmetaobject::prelude::*;
#[derive(QObject, Default)]
struct MyAsyncObject {
base: qt_base_class!(trait QObject),
result: qt_property!(QString; NOTIFY result_changed),
result_changed: qt_signal!(),
recompute_result: qt_method!(fn recompute_result(&self, name: String) {
let qptr = QPointer::from(&*self);
let set_value = qmetaobject::queued_callback(move |val: QString| {
qptr.as_pinned().map(|this| {
this.borrow_mut().result = val;
this.borrow().result_changed();
});
});
std::thread::spawn(move || {
// do stuff asynchronously ...
let r = QString::from("Hello ".to_owned() + &name);
set_value(r);
}).join();
})
}
Re-exports
pub use qttypes;
pub use crate::log::*;
pub use connections::RustSignal;
pub use connections::connect;
pub use connections::Signal;
pub use connections::SignalInner;
pub use future::*;
pub use itemmodel::*;
pub use listmodel::*;
pub use qmetatype::*;
pub use qtdeclarative::*;
pub use qtquickcontrols2::*;
pub use tablemodel::*;
Modules
Signals, slots and connections between them.
Logging facilities and forwarding
Module intended for glob import.
Wrappers around QtCore module.
Macros
Embed files and made them available to the Qt resource system.
This macro must be used once as a type in a struct that derives from QObject. It is anotate from which QObject like trait it is supposed to derive. the field which it annotate will be an internal property holding a pointer to the actual C++ object
This macro can be used to declare a method which will become a meta method.
Equivalent to the Q_PLUGIN_METADATA macro.
This macro can be used as a type of a field and can then turn this field in a Qt property. The first parameter is the type of this property. Then we can have the meta keywords similar to these found in Q_PROPERTY.
Declares a signal
Structs
Wrapper around QByteArray
class.
Wrapper around QJsonArray
class.
Wrapper around QJsonObject
class.
Wrapper around QJsonValue
class.
Internal class used to iterate over a QList
Wrapper around QModelIndex
class.
A wrapper around RefCell
A reference to a RefCell
Same as std::cell::RefMut, but does not allow to move from
A Wrapper around a QPointer
Wrapper around QStringList
class.
Wrapper around QVariantList
typedef.
Wrapper around QVariantMap
typedef.
Internal class used to iterate over a QVariantMap
Enums
Bindings for Qt::BrushStyle
enum.
Bindings for QImage::Format
enum class.
Bindings for QString::NormalizationForm
enum.
Bindings for Qt::PenStyle
enum.
Bindings for QColor::NameFormat
enum class.
Bindings for QColor::Spec
enum class.
Bindings for QPainter::RenderHint
enum.
Bindings for QStandardPaths::StandardLocation
enum.
Bindings for QChar::UnicodeVersion
enum.
Constants
Refer to the documentation of Qt::UserRole
Traits
Trait that is implemented by the QEnum custom derive macro
Trait that is implemented by the QGadget custom derive macro
Trait that is implemented by the QObject custom derive macro
Functions
Create the C++ object and return a C++ pointer to a QObject.
Create a callback to invoke a queued callback in the current thread.
Call the callback once, after a given duration.