Skip to main content
Salta al contingut

El Kirigami amb Rust

Creeu la vostra primera aplicació Kirigami amb Rust

Instal·lació del Kirigami

Abans de començar, haurem d'instal·lar el Kirigami i el Rust a la nostra màquina.

logo of Linux operating system ManjaroManjarologo of Linux operating system Arch LinuxArch
sudo pacman -S cargo cmake extra-cmake-modules kirigami breeze qqc2-desktop-style
logo of Linux operating system openSUSEOpenSUSE
sudo zypper install cargo cmake kf6-extra-cmake-modules kf6-kirigami-devel qt6-quickcontrols2-devel kf6-qqc2-desktop-style
logo of Linux operating system FedoraFedora
sudo dnf install cargo cmake extra-cmake-modules kf6-kirigami2-devel kf6-qqc2-desktop-style

Trobareu més informació sobre les altres distribucions aquí.

Estructura del projecte

Primer crearem la nostra carpeta de projecte (podeu utilitzar les ordres de sota). L'anomenarem kirigami_rust/. Aquesta serà l'estructura del projecte:

kirigami_rust/
├── CMakeLists.txt
├── Cargo.toml
├── build.rs
├── org.kde.kirigami_rust.desktop
└── src/
    ├── main.rs
    └── qml/
        └── Main.qml

Aquest projecte utilitzarà el CMake per cridar el Cargo, que al seu torn construirà el projecte.

El projecte s'anomenarà kirigami_rust i generarà un executable anomenat kirigami_hello.

org.kde.kirigami_rust.desktop

El propòsit principal dels fitxers Desktop Entry és mostrar la vostra aplicació al llançador d'aplicacions en el Linux. Una altra raó per a tenir-los és tenir icones de finestra al Wayland, ja que es requereixen per a dir al compositor «aquesta finestra va amb aquesta icona».

Ha de seguir un esquema de noms DNS invers seguit de l'extensió .desktop com ara org.kde.kirigami_rust.desktop:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Desktop Entry]
Name=Kirigami Tutorial in Rust
Name[ca]=Guia d'aprenentatge del Kirigami en Rust
Name[es]=Tutorial de Kirigami en Rust
Name[fr]=Tutoriel pour Kirigami en Rust
Name[it]=Esercitazione di Kirigami in Rust
Name[nl]=Kirigami handleiding in Rust
Name[sl]=Učbenik Kirigami v Rustu
Name[sv]=Kirigami-handledning i Rust
Name[uk]=Підручник з Kirigami для Rust
Name[x-test]=xxKirigami Tutorial in Rustxx
Exec=kirigami_hello
Icon=kde
Type=Application
Terminal=false
Categories=Utility

CMakeLists.txt

El fitxer CMakeLists.txt s'utilitzarà per a executar el Cargo i instal·lar els fitxers necessaris juntament amb la nostra aplicació. També proporciona certes característiques de qualitat de vida, com assegurar-se que el Kirigami s'instal·la durant la compilació i senyalitzar distribucions de Linux per a instal·lar les dependències necessàries amb l'aplicació.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cmake_minimum_required(VERSION 3.28)

project(kirigami_rust)

find_package(ECM 6.0 REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
include(KDEInstallDirs)
include(ECMUninstallTarget)

include(ECMFindQmlModule)
ecm_find_qmlmodule(org.kde.kirigami REQUIRED)
find_package(KF6 REQUIRED COMPONENTS QQC2DesktopStyle)

add_custom_target(kirigami_rust
    ALL
    COMMAND cargo build --target-dir ${CMAKE_CURRENT_BINARY_DIR}
)

install(
    PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/debug/kirigami_hello
    DESTINATION ${KDE_INSTALL_BINDIR}
)

install(FILES org.kde.kirigami_rust.desktop DESTINATION ${KDE_INSTALL_APPDIR})

El primer que fem és afegir els Mòduls extres del CMake (ECM) de KDE al nostre projecte perquè puguem utilitzar el ecm_find_qml_module per a comprovar que el Kirigami està instal·lat quan s'intenta construir l'aplicació, i si no ho està, falla immediatament. Una altra característica útil de l'ECM és ECMUninstallTarget, que permet desinstal·lar fàcilment l'aplicació amb el CMake si es desitja.

També utilitzem el find_package() del CMake per assegurar-nos que tenim l'estil qqc2-desktop-style, l'estil QML de KDE per a l'escriptori. Aquesta és una de les dues raons per les quals utilitzem el CMake en aquesta guia d'aprenentatge.

Normalment, els projectes Rust es construeixen amb el Cargo, i aquí no serà diferent. Creem un objectiu que simplement executarà el Cargo quan s'executi, i el marcarà amb ALL perquè es construeixi de manera predeterminada. El Cargo construirà l'executable dins del directori binari del CMake (normalment build/).

Per a més informació sobre el CMake, els objectius i el directori binari, vegeu Construir manualment el programari KDE.

Després d'això, simplement instal·lem l'executable kirigami_rust generat pel Cargo al directori binari i l'instal·lem al BINDIR, que sol ser /usr/bin, /usr/local/bin o ~/.local/bin. També instal·lem el fitxer d'escriptori necessari a APPDIR, que sol ser /usr/share/applications o ~/.local/share/applications. Aquesta és la segona raó per la qual utilitzem el CMake en aquesta guia d'aprenentatge.

Per a més informació sobre on s'instal·la el programari de KDE, vegeu Construir manualment el programari de KDE: El pas d'instal·lació.

Ara que ens hem revisat el CMake, vegem els fitxers als quals dedicarem la major part del nostre temps de treball.

Cargo.toml

A continuació tenim un Cargo.toml molt senzill:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[package]
name = "kirigami_hello"
version = "0.1.0"
authors = [ "Konqi the Konqueror <konqi@kde.org>" ]
edition = "2021"
license = "GPLv3"

[dependencies]
cxx = "1.0.95"
cxx-qt = "0.7"
cxx-qt-lib = { version="0.7", features = ["qt_full"] }
cxx-qt-lib-extras = "0.7"

[build-dependencies]
# The link_qt_object_files feature is required for statically linking Qt 6.
cxx-qt-build = { version = "0.7", features = [ "link_qt_object_files" ] }

Consisteix en metadades del projecte i una llista de dependències que el Cargo extraurà automàticament, és a dir, cxx i cxx-qt, que són necessàries per a executar aplicacions Qt escrites en Rust.

build.rs

On al C++ normalment registrareu elements QML amb QML_ELEMENT i el ecm_add_qml_module utilitzant el registre declaratiu, amb el Rust haureu de declarar-ho en un fitxer build script build.rs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
use cxx_qt_build::{CxxQtBuilder, QmlModule};

fn main() {
    CxxQtBuilder::new()
        .qml_module(QmlModule {
            uri: "org.kde.tutorial",
            qml_files: &["src/qml/Main.qml"],
            rust_files: &["src/main.rs"],
            ..Default::default()
        })
        .build();
}

Això és necessari per a fer que el fitxer QML estigui disponible en el punt d'entrada de la nostra aplicació, main.rs.

src/main.rs

El fitxer kirigami_rust/src/main.rs inicialitza el projecte i després carrega el fitxer QML, que consistirà en la interfície d'usuari per a l'aplicació.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#[cxx_qt::bridge]
mod ffi {
    extern "RustQt" {
        #[qobject]
        type DummyQObject = super::DummyRustStruct;
    }
}

#[derive(Default)]
pub struct DummyRustStruct;

use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QQuickStyle, QString, QUrl};
use cxx_qt_lib_extras::QApplication;
use std::env;

fn main() {
    let mut app = QApplication::new();
    let mut engine = QQmlApplicationEngine::new();

    // To associate the executable to the installed desktop file
    QGuiApplication::set_desktop_file_name(&QString::from("org.kde.kirigami_rust"));
    // To ensure the style is set correctly
    let style = env::var("QT_QUICK_CONTROLS_STYLE");
    if style.is_err() {
        QQuickStyle::set_style(&QString::from("org.kde.desktop"));
    }

    if let Some(engine) = engine.as_mut() {
        engine.load(&QUrl::from("qrc:/qt/qml/org/kde/tutorial/src/qml/Main.qml"));
    }

    if let Some(app) = app.as_mut() {
        app.exec();
    }
}

La primera part que està marcada amb la macro del Rust #[cxx_qt::bridge] només crea un QObject fictici a partir d'una estructura Rust fictícia. Això és necessari només per a completar l'ús del QmlModule a l'script de construcció anterior build.rs. Això jugarà un paper més important en una guia d'aprenentatge futura ensenyant com exposar el codi Rust al QML, però per ara el podeu ignorar.

Després d'això comença la part important:

Les línies 12-13 importen les biblioteques Qt necessàries exposades a través de cxx-qt.

Primer creem una instància nova d'una QApplication i després realitzem algunes integracions en les línies 20-26.

Després ve la part que realment crea la finestra de l'aplicació:

28
29
30
    if let Some(engine) = engine.as_mut() {
        engine.load(&QUrl::from("qrc:/qt/qml/org/kde/tutorial/src/qml/Main.qml"));
    }

L'URL llarg qrc:/qt/qml/org/kde/tutorial/src/qml/Main.qml correspon al fitxer Main.qml d'acord amb el Sistema de recursos Qt, i segueix aquest esquema: <resource_prefix><import_URI><QML_dir><file>.

En altres paraules: el prefix de recurs predeterminat qrc:/qt/qml/ + l'URI d'importació org/kde/tutorial (establert a build.rs, separat per barres en lloc de punts) + el directori QML src/qml/ + el fitxer QML Main.qml.

src/qml/Main.qml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Includes relevant modules used by the QML
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami

// Provides basic features needed for all kirigami applications
Kirigami.ApplicationWindow {
    // Unique identifier to reference this object
    id: root

    width: 400
    height: 300

    // Window title
    title: "Hello World"

    // Set the first page that will be loaded when the app opens
    // This can also be set to an id of a Kirigami.Page
    pageStack.initialPage: Kirigami.Page {
        Controls.Label {
            // Center label horizontally and vertically within parent object
            anchors.centerIn: parent
            text: "Hello World!"
        }
    }
}

Aquí és on manejarem el frontal de la nostra aplicació.

Si coneixeu alguna cosa de JavaScript, gran part de QML us resultarà familiar (encara que té les seves pròpies peculiaritats). Si teniu ganes de provar alguna cosa pel vostre compte, la documentació de les Qt té una gran quantitat de material sobre aquest llenguatge. Al llarg d'aquestes guies d'aprenentatge, centrarem gran part de la nostra atenció en el codi en QML, on podrem emprar el Kirigami per a aprofitar-lo al màxim.

Per ara, centrem-nos en Main.qml. Primer importarem diversos mòduls importants:

  • QtQuick, la biblioteca estàndard utilitzada en les aplicacions QML.
  • QtQuick Controls, que proporciona una sèrie de controls estàndard que podem utilitzar perquè les nostres aplicacions siguin interactives.
  • QtQuick Layouts, que proporciona eines per a col·locar els components dins de la finestra de l'aplicació.
  • El Kirigami, que proporciona una sèrie de components adequats per a crear aplicacions que funcionen en dispositius de formes i mides diferents.

Després arribem al nostre element base, la Kirigami.ApplicationWindow, que proporciona algunes característiques bàsiques necessàries per a totes les aplicacions escrites amb el Kirigami. Aquesta és la finestra que contindrà cadascuna de les nostres pàgines, les seccions principals de la nostra interfície d'usuari.

Després, establim la propietat id de la finestra a "root". Els ID són útils perquè ens permeten fer referència de forma única a un component, fins i tot si en tenim diversos del mateix tipus.

També establim la propietat title de la finestra a "Hola món".

Després establirem la primera pàgina de la nostra pila de pàgines. La majoria de les aplicacions escrites amb el Kirigami estan organitzades com una pila de pàgines, cada pàgina conté els components relacionats adequats per a una tasca específica. Per ara, el mantenim senzill i ens cenyim a una sola pàgina. pageStack és una pila inicialment buida de pàgines proporcionades per Kirigami.ApplicationWindow, i amb pageStack.initialPage: Kirigami.Page{...} establim la primera pàgina presentada en carregar l'aplicació a una Kirigami.Page. Aquesta pàgina contindrà tot el nostre contingut.

Finalment, incloem en la nostra pàgina un Controls.Label que ens permetrà inserir text a la nostra pàgina. Utilitzarem anchors.centerIn: parent per a centrar la nostra etiqueta horitzontalment i verticalment dins de l'element pare. En aquest cas, el component principal de la nostra etiqueta és Kirigami.Page. L'últim que hem de fer és configurar el text: text: "Hello World!".

Compilar i instal·lar l'aplicació

Hauríeu de trobar l'executable generat kirigami_hello a build/debug/kirigami_hello i podeu executar-lo directament o amb cargo run, però no tindrà una icona de finestra. Per a solucionar-ho, primer instal·larem l'aplicació.

Executeu el següent:

cmake -B build --install-prefix ~/.local
cmake --build build/
cmake --install build/

Amb la primera ordre, el CMake cercarà el Kirigami i el qqc2-desktop-style.

Amb la segona ordre, el CMake construirà l'objectiu kirigami_rust, que només crida cargo build --target-dir build/. Aquest pas trigarà una estona a completar-se, però la propera vegada que repetiu la segona ordre del CMake serà més ràpida o no caldrà de compilar res.

En el tercer pas, el CMake instal·larà l'executable kirigami_hello a ~/.local/bin/kirigami_hello i el fitxer d'escriptori a ~/.local/share/applications, i apareixerà una entrada nova al menú anomenada «Guia d'aprenentatge del Kirigami en Rust».

Obriu l'entrada de menu i heus aquí! Ara veureu aparèixer la vostra primera aplicació escrita amb el Kirigami.

Captura de pantalla de l'aplicació generada amb el Kirigami

Per a executar la nova aplicació QML en mode de mòbil, podeu utilitzar QT_QUICK_CONTROLS_MOBILE=1:

QT_QUICK_CONTROLS_MOBILE=1 kirigami_hello

Si heu compilat el projecte manualment amb el CMake i per algun motiu voleu desinstal·lar el projecte, podeu executar:

cmake --build build/ --target uninstall