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 QObjects 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 connections::RustSignal;
pub use connections::connect;
pub use connections::Signal;
pub use connections::SignalInner;
pub use qttypes;
pub use crate::log::*;
pub use future::*;
pub use itemmodel::*;
pub use listmodel::*;
pub use qmetatype::*;
pub use qtdeclarative::*;
pub use qtquickcontrols2::*;
pub use tablemodel::*;

Modules§

connections
Signals, slots and connections between them.
future
itemmodel
listmodel
log
Logging facilities and forwarding
prelude
Module intended for glob import.
qmetatype
qrc
qtcore
Wrappers around QtCore module.
qtdeclarative
qtquickcontrols2
scenegraph
tablemodel

Macros§

qrc
Embed files and made them available to the Qt resource system.
qt_base_class
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
qt_method
This macro can be used to declare a method which will become a meta method.
qt_plugin
Equivalent to the Q_PLUGIN_METADATA macro.
qt_property
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.
qt_signal
Declares a signal

Structs§

QBrush
Wrapper around QBrush class.
QByteArray
Wrapper around QByteArray class.
QColor
Wrapper around QColor class.
QDate
Wrapper around QDate class.
QDateTime
Wrapper around QDateTime class.
QImage
Wrapper around QImage class.
QJsonArray
Wrapper around QJsonArray class.
QJsonObject
Wrapper around QJsonObject class.
QJsonValue
Wrapper around QJsonValue class.
QLineF
Bindings for QLineF class.
QListIterator
Internal class used to iterate over a QList
QMargins
Bindings for QMargins class.
QModelIndex
Wrapper around QModelIndex class.
QObjectBox
A wrapper around RefCell, whose content cannot be move in memory
QObjectPinned
A reference to a RefCell, where T is a QObject, which does not move in memory
QObjectRefMut
Same as std::cell::RefMut, but does not allow to move from
QPainter
Wrapper around QPainter class.
QPen
Wrapper around QPen class.
QPixmap
Wrapper around QPixmap class.
QPoint
Bindings for QPoint class.
QPointF
Bindings for QPointF class.
QPointer
A Wrapper around a QPointer
QRectF
Bindings for QRectF class.
QRgb
QRgba64
QSettings
Wrapper around QSettings class.
QSize
Bindings for QSize class.
QSizeF
Bindings for QSizeF class.
QString
Wrapper around QString class.
QStringList
Wrapper around QStringList class.
QTime
Wrapper around QTime class.
QUrl
Wrapper around QUrl class.
QVariant
Wrapper around QVariant class.
QVariantList
Wrapper around QVariantList typedef.
QVariantMap
Wrapper around QVariantMap typedef.
QVariantMapIterator
Internal class used to iterate over a QVariantMap

Enums§

BrushStyle
Bindings for Qt::BrushStyle enum.
ImageFormat
Bindings for QImage::Format enum class.
NormalizationForm
Bindings for QString::NormalizationForm enum.
PenStyle
Bindings for Qt::PenStyle enum.
QColorNameFormat
Bindings for QColor::NameFormat enum class.
QColorSpec
Bindings for QColor::Spec enum class.
QPainterRenderHint
Bindings for QPainter::RenderHint enum.
QStandardPathLocation
Bindings for QStandardPaths::StandardLocation enum.
UnicodeVersion
Bindings for QChar::UnicodeVersion enum.

Constants§

USER_ROLE
Refer to the documentation of Qt::UserRole

Traits§

QEnum
Trait that is implemented by the QEnum custom derive macro
QGadget
Trait that is implemented by the QGadget custom derive macro
QObject
Trait that is implemented by the QObject custom derive macro

Functions§

into_leaked_cpp_ptr
Create the C++ object and return a C++ pointer to a QObject.
queued_callback
Create a callback to invoke a queued callback in the current thread.
single_shot
Call the callback once, after a given duration.

Type Aliases§

qreal