桌面应用程序是原生的、快速的、安全的,并提供Web应用程序无法比拟的体验。
Rust 是一种低级静态类型多范式编程语言,专注于安全性和性能,解决了 C/C++ 长期以来一直在努力解决的问题,例如内存错误和构建并发程序。
在桌面应用程序开发中使用的所有编程语言中,Rust逐渐成为受欢迎的语言之一。Rust被广泛认为是可靠的、高性能的、多产的和通用的。事实上,许多组织正在将其应用程序迁移到Rust。GNOME Linux开发环境就是一个例子。
1、Rust Qt框架选择
Rust有几个Qt绑定。最受欢迎的是Ritual,CXX-Qt和qmetaobject
。Ritual不再维护,qmetaobject
不支持QWidgets
。所以CXX-Qt是我们目前最好的选择
Rust是一门相对较新的语言。生态系统也是如此。CXX-Qt不如PyQt成熟。但它在去那里的路上。目前最新的版本已经有了一个好的和简单的API。
2、搭建rust和qt
开始使用Rust和Qt
使用以下命令安装Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
如果您https://rustup.rs/要确保一切正常,请在终端中运行以下命令:
rustc --version
接下来,安装Qt:
# Ubuntu
sudo apt install qt6-base-dev qt6-declarative-dev
# Fedora
sudo dnf install qt6-qtbase-devel qt6-qtdeclarative-devel
# If you are unsure. Just install all Qt dependencies
# It is no more than 200 MB
sudo apt install qt6*
sudo dnf install qt6*
要检查Qt是否成功安装,请检查您是否能够运行以下命令:
qmake --version
应用组件
CXX-Qt是Rust Qt绑定。它为Qt代码和Rust之间的桥接提供了一种安全的机制。与典型的一对一绑定不同。CXX-Qt使用CXX来桥接Qt和Rust。这提供了更强大的代码,安全的API,以及两个代码之间的安全多线程。与之前的版本不同。在最新版本中,您不需要接触任何C++代码。
QML是一种开发用户界面的编程语言。它非常易读,因为它提供了类似JSON的语法。QML还支持命令式JavaScript表达式和动态属性绑定;这将有助于编写凯撒密码应用程序。如果您需要复习,请参阅此QML介绍。
Qt应用演示
为了演示如何使用Qt和Rust,我们将构建一个简单的“Hello World”应用程序。
创建Rust项目
首先,我们需要创建一个Rust项目,如下所示:
❯ cargo new --bin demo Created binary (application) `demo` package
接下来,打开Cargo.toml
文件并添加依赖项:
[dependencies] cxx = "1.0.83" cxx-qt = "0.5" cxx-qt-lib = "0.5" [build-dependencies] cxx-qt-build = "0.5"
现在,让我们为应用程序创建入口点。在src/main.rs
文件中,我们将初始化GUI应用程序和QML引擎。然后我们将加载QML文件并告诉应用程序启动:
use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QUrl};
fn main() {
// Create the application and engine
let mut app = QGuiApplication::new();
let mut engine = QQmlApplicationEngine::new();
// Load the QML path into the engine
if let Some(engine) = engine.as_mut() {
engine.load(&QUrl::from("qrc:/main.qml"));
}
// Start the app
if let Some(app) = app.as_mut() {
app.exec();
}
}
为了在Rust和Qt之间建立通信,我们将在src/cxxqt_oject.rs
文件中定义对象:
// src/cxxqt_object.rs
#[cxx_qt::bridge]
mod my_object {
#[cxx_qt::qobject(qml_uri = "demo", qml_version = "1.0")]
#[derive(Default)]
pub struct Hello {}
impl qobject::Hello {
#[qinvokable]
pub fn say_hello(&self) {
println!("Hello world!")
}
}
}
属性宏用于启用CXX-Qt功能。
-
#[cxx_qt::bridge]
:标记Rust模块能够与C++交互 -
#[cxx_qt::qobject]
:将Rust结构体作为QObject子类公开给Qt -
#[qinvokable]
:将QObject上的函数作为Q_INVOKABLE暴露给QML和C++。
接下来,我们将创建一个名为struct
的Hello
,它派生自qobject
traits。然后我们可以实现常规的Rust函数来打印问候语:
// src/main.rs + mod cxxqt_object; use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QUrl};
设计UI
我们将使用QML来设计用户界面。UI文件位于qml/main.qml
文件中:
Hello {
id: hello
}
Column {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
/* space between widget */
spacing: 10
Button {
text: "Say Hello!"
onClicked: hello.sayHello()
}
}
}
如果你仔细观察sayHello
函数,你会注意到CXX-Qt将Rust函数的snake case转换为camelCase C++约定。现在,我们的QML代码看起来并不奇怪!
接下来,我们必须使用Qt资源文件告诉Qt QML的位置。它应该位于qml/qml.qrc
文件中:
main.qml
构建应用程序
最后一步是构建应用程序。为了教Rust如何构建cxxqt_object.rs
和QML文件,我们需要首先在build.rs
文件中定义它:
fn main() {
CxxQtBuilder::new()
// Link Qt's Network library
// - Qt Core is always linked
// - Qt Gui is linked by enabling the qt_gui Cargo feature (default).
// - Qt Qml is linked by enabling the qt_qml Cargo feature (default).
// - Qt Qml requires linking Qt Network on macOS
.qt_module("Network")
// Generate C++ from the `#[cxx_qt::bridge]` module
.file("src/cxxqt_object.rs")
// Generate C++ code from the .qrc file with the rcc tool
// https://doc.qt.io/qt-6/resources.html
.qrc("qml/qml.qrc")
.setup_linker()
.build();
}
最终的结构应该是这样的:
现在,让我们使用cargo check
来确保我们有一个正确的代码。
# `cargo c` is an alias to `cargo check` ❯ cargo c Finished dev [unoptimized + debuginfo] target(s) in 0.04s
最后,让我们运行应用程序:
⬢ ❯ cargo --quiet r Compiling demo v0.1.0 Finished dev [unoptimized + debuginfo] target(s) in 0.49s Running `target/debug/demo` Hello world!
Rust和qt的结合会带来新的碰撞和可能。