#qt #class #object

sys qt_core

QtCore C++ 库绑定

18 个不稳定版本 (5 个破坏性更改)

0.5.0 2020年3月21日
0.5.0-alpha.12020年2月17日
0.4.1 2019年12月22日
0.4.0 2019年11月2日
0.1.2 2016年11月20日

#257 in GUI

Download history 249/week @ 2024-03-13 485/week @ 2024-03-20 634/week @ 2024-03-27 279/week @ 2024-04-03 288/week @ 2024-04-10 284/week @ 2024-04-17 300/week @ 2024-04-24 322/week @ 2024-05-01 261/week @ 2024-05-08 284/week @ 2024-05-15 282/week @ 2024-05-22 230/week @ 2024-05-29 234/week @ 2024-06-05 290/week @ 2024-06-12 359/week @ 2024-06-19 202/week @ 2024-06-26

1,101 每月下载
214 个工具包(15 个直接) 中使用

MIT/Apache

37MB
291K SLoC

Rust 248K SLoC // 0.0% comments C++ 43K SLoC // 0.0% comments

这是一个正在进行中的项目,因此 API 将在将来进行重大更改。一些方法缺失,一些方法使用不便。尽管没有标记为不安全,但一些方法仍然是不安全的。用户必须像往常一样仔细跟踪对象的拥有权,因为 Rust 的常规保证不起作用。这将在未来得到改善。请将任何问题报告给 问题跟踪器

启动

Qt 需要在应用程序开始时构建一个应用程序对象。(某些类可以在没有它的情况下使用,应用程序对象需要在 C++ 的 main 函数中可用 argcargv。在 Rust 中这样做有点棘手,因为 argcargv 不可用。 CoreApplication::init 是一个便利函数,它执行应用程序对象的适当创建,并在应用程序退出时使用适当的返回码终止进程

extern crate qt_core;
use qt_core::core_application::CoreApplication;

fn main() {
  CoreApplication::init(|app| {
    // initialization goes here
    CoreApplication::exec()
  })
}

请注意,如果您使用 qt_guiqt_widgets 工具包,您应分别使用 qt_gui::gui_application::GuiApplicationqt_widgets::application::Application 而不是 CoreApplication

CoreApplication::exec 启动主事件循环。在您的初始化代码完成后,任何其他 Rust 代码只有在将其绑定到槽时才会由 Qt 执行

extern crate qt_core;
use qt_core::core_application::CoreApplication;
use qt_core::variant::Variant;
use qt_core::variant_animation::VariantAnimation;
use qt_core::connection::Signal;
use qt_core::slots::SlotVariantRef;

fn main() {
  CoreApplication::init(|app| {
    let slot1 = SlotVariantRef::new(|value| {
      println!("value_changed: {}",
               value.to_string().to_std_string());
    });

    let mut animation = VariantAnimation::new();
    animation.signals().value_changed().connect(&slot1);
    animation
        .signals()
        .finished()
        .connect(&app.slots().quit());
    animation.set_start_value(&Variant::new0(1));
    animation.set_end_value(&Variant::new0(5));
    animation.set_duration(5000);
    animation.start(());
    CoreApplication::exec()
  })
}

命名

Qt 的类和方法名称根据 Rust 的命名约定进行修改。删除了 Q 前缀。Qt 的每个包含文件都转换为子模块。原始 C++ 名称始终列在文档中,因此您可以通过原始名称搜索 Rust 等效项。

类型和所有权

Qt 工具包使用两种处理 C++ 对象所有权的策略。

类似于值的类型(例如 QStringQVector 等)在 Rust 中由拥有结构体类型表示(例如 qt_core::string::String)。值存储在 Rust 为结构体本身预留的内存中。该类型的 Drop 实现将调用 C++ 析构函数以确保值的正确初始化。无法将此类对象的所有权转移到 C++ 方面。

其他类型都存储在 C++ 堆中,并使用原始指针和智能指针进行处理。原始指针类型(例如 *mut qt_core::object::Object)与 C++ 中的指针相同。无法保证指针在任何时刻都是有效的,空指针表示没有对象。原始指针中也没有关于所有权的任何信息。一些 C++ 函数可能会返回一个原始对象并期望调用者获取所有权,而其他函数则保留所有权并可能在任何时候删除对象。与 C++ 类似,调用者需要参考函数文档并手动处理所有权。

当确定对象的所有权属于调用者时(例如在构造函数中),原始指针 *mut T 被封装到 cpp_core::CppBox<T> 中。这个结构拥有对象并在丢弃时将其删除。这允许你在需要将所有权转移回 C++ 端时移动原始指针。

Qt 框架中的引用(&T&mut T)与原始指针没有太大区别。它们出现在与 C++ 中引用使用相同的位置,但它们不能持有 Rust 通常强制执行的引用保证。引用的生存期被简单地设置:所有输入引用都必须具有相同的生存期,输出引用与输入引用具有相同的生存期。如果没有输入引用,输出引用具有 'static 生存期。

可以预期,原始指针将被 CppBox 和引用替换,并且引用将持有其保证。然而,这需要手动注释方法,因此实现这种改进并不容易。

依赖项