cpp
crate
Olivier Goffart
https://woboq.com
KDE | |
Nokia (Qt) 2007 - 2011 | |
Woboq GmbH 2011 - |
class Status : public QObject
{
Q_OBJECT
Q_PROPERTY(QString statusText READ statusText
WRITE setStatusText NOTIFY statusTextChanged)
QString m_statusText;
public:
QString statusText() const;
public slots:
void setStatusText(const QString &txt);
signals:
void statusTextChanged();
};
Window {
property Status model;
MouseArea {
anchors.fill: parent;
onClicked: model.setStatusText("Clicked");
}
StatusBar {
anchors.bottom: parent.bottom;
text: qsTr("Status: ") + model.statusText;
}
}
// In wrapper.cpp
extern "C" QLabel *showNewLabel(char *text)
{
auto label = new QLabel(QString::fromUtf8(text));
label->show();
return label;
}
// ... and many more wrapping function
// in some rust module:
#[no_mangle]
extern fn showNewLabel(text : &CStr) -> *mut c_void;
// ...
[build-dependencies]
bindgen = "0.20"
Automatically generates extern
functions.
{
"cppFile": "src/Bindings.cpp",
"rust": {
"dir": "rust",
"interfaceModule": "interface",
"implementationModule": "implementation"
},
"objects": {
"Todos": {
"type": "List",
"properties": {
"count": {
"type": "quint64"
},
"activeCount": {
"type": "quint64"
}
},
"itemProperties": {
"completed": {
"type": "bool",
"write": true
},
"description": {
"type": "QString",
"write": true
}
},
"functions": {
"add": {
"return": "void",
"mut": true,
"arguments": [{
"name": "description",
"type": "QString"
}]
},
"remove": {
"return": "bool",
"mut": true,
"arguments": [{
"name": "index",
"type": "quint64"
}]
},
"setAll": {
"return": "void",
"mut": true,
"arguments": [{
"name": "completed",
"type": "bool"
}]
},
"clearCompleted": {
"return": "void",
"mut": true,
"arguments": []
}
}
}
}
}
[package]
build = "build.rs"
[dependencies]
cpp = "0.4"
[build-dependencies]
cpp_build = "0.4"
cpp!{{ #include<QLabel> }}
//...
unsafe {
let text : &CStr = /* ... */;
let label = cpp!([text as "const char*"] -> *mut c_void as "QLabel*" {
auto label = new QLabel(QString::fromUtf8(text));
label->show();
return label;
});
// ...
}
build.rs
extern crate cpp_build;
fn main() {
cpp_build::build("src/lib.rs");
}
cpp!
and cpp_class!
macro. extern "C"
functions in a .cpp file.
cpp
cratecpp_macro
cratefrom the qmetaobject
crate
cpp_class!(pub unsafe struct QImage as "QImage");
impl QImage {
pub fn load_from_file(filename : QString) -> Self {
cpp!(unsafe [filename as "QString"] -> QImage as "QImage" {
return QImage(filename);
})
}
pub fn new(size : QSize, format : ImageFormat) -> Self {
cpp!(unsafe [size as "QSize", format as "QImage::Format" ] -> QImage as "QImage" {
return QImage(size, format);
})
}
pub fn size(&self) -> QSize {
cpp!(unsafe [self as "const QImage*"] -> QSize as "QSize" { return self->size(); })
}
pub fn format(&self) -> ImageFormat {
cpp!(unsafe [self as "const QImage*"] -> ImageFormat as "QImage::Format" { return self->format(); })
}
pub fn fill(&mut self, color: QColor) {
cpp!(unsafe [self as "QImage*", color as "QColor"] { self->fill(color); })
}
pub fn set_pixel_color(&mut self, x:u32, y: u32, color: QColor) {
cpp!(unsafe [self as "QImage*", x as "int", y as "int", color as "QColor"]
{ self->setPixelColor(x, y, color); })
}
pub fn get_pixel_color(&mut self, x:u32, y: u32) -> QColor {
cpp!(unsafe [self as "QImage*", x as "int", y as "int"] -> QColor as "QColor"
{ return self->pixelColor(x, y); })
}
//...
}
cpp!{{
class Rust_QAbstractListModel : QAbstractListModel {
TraitObject rust_object; // *mut dyn QAbstractListModel
public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
return rust!(qalm_data [rust_object : &QAbstractListModel as "TraitObject",
index : QModelIndex as "QModelIndex", role : i32 as "int"]
-> QVariant as "QVariant" {
rust_object.data(index, role)
});
}
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override {
return rust!(qaml_setData [rust_object : &mut QAbstractListModel as "TraitObject",
index : QModelIndex as "QModelIndex",
value : QVariant as "QVariant",
role : i32 as "int"] -> bool as "bool" {
rust_object.set_data(index, &value, role)
});
}
int rowCount(const QModelIndex & = QModelIndex()) const override {
return rust!(qaml_rowCount [rust_object : &QAbstractListModel as "TraitObject"]
-> i32 as "int" {
rust_object.row_count()
});
}
//...
};
}}
#[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();
}
Olivier Goffart
olivier@woboq.com
Twitter:
@woboq