ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

QtQuick的Rust绑定 [qmetaobject]

2021-08-06 23:02:50  阅读:406  来源: 互联网

标签:QtQuick name changed btnTest qmetaobject qml Greeter Rust qt


参考 https://github.com/woboq/qmetaobject-rs 第一步:   安装qt,需要使用其中的qmake,将qmake路径放置环境变量中。   如果vscode或者idea中的终端不识别qmake但是在系统的powershell中可以,注意使用管理模式运行 第二步:创建rust项目
cargo new qt_rust_dome
第三步:在项目中创建build.rs
use semver::Version;
fn main() {
    eprintln!("cargo:warning={:?}", std::env::vars().collect::<Vec<_>>());
    let qt_include_path = std::env::var("DEP_QT_INCLUDE_PATH").unwrap();
    let qt_library_path = std::env::var("DEP_QT_LIBRARY_PATH").unwrap();
    let qt_version = std::env::var("DEP_QT_VERSION")
        .unwrap()
        .parse::<Version>()
        .expect("Parsing Qt version failed");
    let mut config = cpp_build::Config::new();
    if cfg!(target_os = "macos") {
        config.flag("-F");
        config.flag(&qt_library_path);
    }
    if qt_version >= Version::new(6, 0, 0) {
        config.flag_if_supported("-std=c++17");
        config.flag_if_supported("/std:c++17");
    }
    config.include(&qt_include_path).build("src/lib.rs");
    for minor in 7..=15 {
        if qt_version >= Version::new(5, minor, 0) {
            println!("cargo:rustc-cfg=qt_{}_{}", 5, minor);
        }
    }
    let mut minor = 0;
    while qt_version >= Version::new(6, minor, 0) {
        println!("cargo:rustc-cfg=qt_{}_{}", 6, minor);
        minor += 1;
    }
}
第四步:修改Cargo.toml
[package]
name = "qml_rust_dome"
version = "0.1.0"
edition = "2018"
build="build.rs"  // 注意这句话要添加上

[dependencies]
qmetaobject="*"  // qmetaobject
qttypes = { version = "0.2.2", features = [ "qtquick" ] }
cstr="0.2"
cpp = "0.5"
[build-dependencies]
cpp_build = "0.5" // 部分内容需要cpp编译?
semver="1.0.3"
第五步:创建qml文件
//main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
//这里引入模板
import Greeter 1.0
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    //写一个qml的信号
    signal qml_Signal_btnTest_Clicked()
    Button {
        id: btnTest
        x: 251
        y: 187
        text: qsTr("btnTest")
        onClicked: {
            // 使用rust中的Greeter
            qobj.name="btnTest set the name"
            console.log("qml 调用Greeter中的add函数返回:",qobj.add(10,20)) // Greeter中的方法
            qml_Signal_btnTest_Clicked() //qml发送信号,Greeter接收
        }
    }
    //定义qml中的槽函数
    function slot_name_changed(){
        console.log('qml slot_name_changed 收到 onSignal_name_changed 的信号')
    }
    Greeter{
        id:qobj
        // 可以如此关联信号和槽,也可以在Component.onCompleted中关联
        // 如果同时关联,就同时执行
        onSignal_name_changed:{
            console.log('qml Greeter组件收到 onSignal_name_changed 信号')
        }
    }
    //组件加载完成后 关联信号和槽
    Component.onCompleted: {
        //Qml对象的信号关联到Greeter的槽函数
        qml_Signal_btnTest_Clicked.connect(qobj.slot_btnTest_Clicked)
        //把Greeter的信号关联到Qml
        qobj.onSignal_name_changed.connect(slot_name_changed)
    }
}

最后main.rs

//main.rs
extern crate qmetaobject;
use qmetaobject::*;
use cstr::cstr;
// 配置资源文件
// as前面的qml是文件目录,as后面的是虚拟路径
qrc!(my_resource,
    "qml" as "qml" {
        "main.qml",
    },
);
#[derive(QObject,Default)]
struct Greeter{
    //todo base是什么?
    base:qt_base_class!(trait QObject),
    // 定义一个属性,属性改变时发送 slot_name_changed 信号
    name:qt_property!(QString; NOTIFY signal_name_changed),
    // 定义一个信号
    signal_name_changed:qt_signal!(),
    // 定义一个槽
    slot_btnTest_Clicked:qt_method!(fn slot_btnTest_Clicked(&self){
        println!("--> slot_btnTest_Clicked:{}",self.name);
    }),
    // qml也可以直接调用
    add:qt_method!(fn add(&self,a:i32,b:i32)->i32{
        a+b
    }),
}
fn main() {
    // 注册资源文件
    my_resource();
    // 将Greeter注册到qml中 
    qml_register_type::<Greeter>(cstr!("Greeter"), 1, 0, cstr!("Greeter"));
    // 创建一个QML engine
    let mut engine=QmlEngine::new();
    engine.load_file("qrc:/qml/main.qml".into());
    engine.exec();
}

 

标签:QtQuick,name,changed,btnTest,qmetaobject,qml,Greeter,Rust,qt
来源: https://www.cnblogs.com/zsb/p/15110641.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有