[−][src]Crate qmetaobject
This crate implements binding to the Qt API which allow to use QML from a rust application.
Example:
extern crate qmetaobject; use qmetaobject::*; #[macro_use] extern crate cstr; // 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), // Decalare `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 { return (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 Greeter 1.0 // import our Rust classes Window { visible: true; Greeter { // Instentiate the rust struct id: greeter; name: 'World'; // set a property } Text { anchors.centerIn: parent; // Call a method text: greeter.compute_greetings('hello'); } }"#.into()); engine.exec(); }
Basic types
The re-exported module 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:
#[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, tou can use QPointer.
Threading
The QML engine only runs in a single thread. And probably all the QObject 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:
#[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(|self_| { self_.borrow_mut().result = val; self_.borrow().result_changed(); }); }); std::thread::spawn(move || { // do stuff asynchroniously ... let r = QString::from("Hello ".to_owned() + &name); set_value(r); }).join(); }) }
Re-exports
pub use qttypes::*; |
pub use itemmodel::*; |
pub use listmodel::*; |
pub use qtdeclarative::*; |
pub use qmetatype::*; |
pub use connections::RustSignal; |
pub use connections::connect; |
pub use connections::CppSignal; |
pub use connections::SignalCppRepresentation; |
pub use qtquickcontrols2::*; |
pub use future::*; |
Modules
connections | |
future | |
itemmodel | |
listmodel | |
qmetatype | |
qrc | |
qtdeclarative | |
qtquickcontrols2 | |
qttypes | |
scenegraph |
Macros
qrc | Macro to 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
QMessageLogContext | Wrapper for Qt's QMessageLogContext |
QObjectBox | A wrapper around RefCell |
QObjectPinned | A reference to a RefCell |
QObjectRefMut | Same as std::cell::RefMut, but does not allow to move from |
QPointer | A Wrapper around a QPointer |
Enums
QtMsgType | Wrap Qt's QtMsgType 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
install_message_handler | Wrap qt's qInstallMessageHandler. Useful in order to forward the log to a rust logging framework |
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. |