Skip to main content
Gå till innehåll

Kirigami med Rust

Skapa ditt första Kirigami-program med Rust

Installera Kirigami

Innan vi börjar måste vi installera Kirigami och Rust på datorn.

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

Ytterligare information för andra distributioner finns här.

Projektstruktur

Först skapar vi vår projektkatalog (du kan använda kommandona nedan). Vi kallar vår kirigami_rust/.

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

Projektet använder CMake för att anropa Cargo, som i sin tur bygger projektet.

Projektet kallas kirigami_rust och det genererar en körbar fil som heter kirigami_hello.

org.kde.kirigami_rust.desktop

Det primära syftet med Desktop Entry-filer är att visa programmet i programstart på Linux. En annan anledning att ha dem är att ha fönsterikoner på Wayland, eftersom de måste tala om för sammansättningen att "det här fönstret hör ihop med den här ikonen".

Det måste följa ett omvänt domännamnsschema följt av tillägget .desktop såsom 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[tr]=Rust ile Kirigami Öğreticisi
Name[uk]=Підручник з Kirigami для Rust
Exec=kirigami_hello
Icon=kde
Type=Application
Terminal=false
Categories=Utility

CMakeLists.txt

Filen CMakeLists.txt används för att köra Cargo och för att installera nödvändiga filer tillsammans med vårt program. Den tillhandahåller också vissa livskvalitetsfunktioner, som att se till att Kirigami installeras under kompilering och för att signalera till Linux-distributioner att installera nödvändiga beroenden med programmet.

 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})

Det första vi gör är att lägga till KDE:s Extra CMake Modules (ECM) i vårt projekt så att vi kan använda ecm_find_qml_module för att kontrollera att Kirigami är installerat när vi försöker bygga programmet, och om det inte är det misslyckas programmet omedelbart. En annan användbar ECM-funktion är ECMUninstallTarget, som gör det möjligt att enkelt avinstallera programmet med CMake om så önskas.

Vi använder också CMake find_package() för att säkerställa att vi har qqc2-desktop-style, KDE:s QML-stil för skrivbordet. Det är en av de två anledningarna till att vi använder CMake i den här handledningen.

Vanligtvis byggs Rust-projekt med Cargo, och det är inte annorlunda här. Vi skapar ett mål som helt enkelt kör Cargo när det körs, och markerar det med ALL så att det normalt byggs. Cargo bygger den körbara filen inuti CMake binärkatalogen (vanligtvis build/).

För mer information om CMake, mål och binärkatalogen, se Bygga KDE-programvara manuellt.

Efter det installerar vi helt enkelt den körbara filen kirigami_rust som genererats av Cargo i binärkatalogen och installerar den i BINDIR, som vanligtvis är /usr/bin, /usr/local/bin eller ~/.local/bin. Vi installerar också den nödvändiga skrivbordsfilen i APPDIR, som vanligtvis är /usr/share/applications eller ~/.local/share/applications. Det är den andra anledningen till att vi använder CMake i den här handledningen.

För mer information om var KDE-programvara är installerad, se Bygga KDE-programvara manuellt: Installationssteget.

Nu när vi har tagit hand om CMake, låt oss titta på filerna vi ska spendera den största delen av tiden att arbeta med.

Cargo.toml

Därefter har vi en väldigt enkel Cargo.toml:

 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" ] }

Den består av projektets metadata och en lista över beroenden som hämtas automatiskt av Cargo, nämligen cxx och cxx-qt, vilka är nödvändiga för att köra Qt-program skrivna i Rust.

build.rs

Medan man vanligtvis registrerar QML-element med QML_ELEMENT och ecm_add_qml_module med hjälp av deklarativ registrering i C++, måste man deklarera det i ett byggskript build.rs i Rust:

 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();
}

Det är nödvändigt för att göra QML-filen tillgänglig för startpunkten i vårt program, main.rs.

src/main.rs

Filen kirigami_rust/src/main.rs initierar projektet och laddar sedan QML-filen, som programmets användargränssnitt består av.

 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();
    }
}

Den första delen som är markerad med Rust-makrot #[cxx_qt::bridge] skapar bara ett QObject från en Rust-struktur. Den behövs bara för att slutföra användningen av QmlModule i det tidigare byggskriptet build.rs. Den spelar en större roll i en framtida handledning som lär ut hur man exponerar Rust-kod i QML, men för tillfället kan du ignorera det.

Efter det börjar den viktiga delen:

Raderna 12-13 importerar de nödvändiga Qt-biblioteken som exponeras via cxx-qt.

Vi skapar först en ny instans av en QApplication och utför sedan några integreringar på raderna 20-26.

Sedan kommer den del som faktiskt skapar programfönstret:

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

Den långa webbadressen qrc:/qt/qml/org/kde/tutorial/src/qml/Main.qml motsvarar filen Main.qml enligt Qt:s resurssystem, och följer det här schemat: <resurs_prefix><import_webbadress><QML_katalog><fil>.

Med andra ord: det vanliga resursprefixet qrc:/qt/qml/ + importsökvägen org/kde/tutorial (anges i build.rs, separerade med snedstreck istället för punkter) + QML-katalogen src/qml/ + QML-filen 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!"
        }
    }
}

Här är stället där vi hanterar vårt förgrundsprogram.

Om du kan lite Javascript ser mycket av QML bekant ut (även om det har sina egenheter). Qt:s dokumentation har en omfattande mängd material om språket om du känner för att prova något på egen hand. Genom alla de här handledningarna kommer vi att fokusera mycket av vår uppmärksamhet på vår QML-kod, där vi kan använda Kirigami för att få ut så mycket som möjligt av den.

Låt oss för tillfället fokusera på Main.qml. Först importerar vi ett antal viktiga moduler:

  • QtQuick, standardbiblioteket som används i QML-program.
  • QtQuick Controls, som tillhandahåller ett antal standardkontroller som vi kan använda för att göra vårt program interaktivt.
  • QtQuick Layouts, som tillhandahåller verktyg för att placera komponenter inom programmets fönster.
  • Kirigami, som tillhandahåller ett antal komponenter lämpade för att skapa program som fungerar över apparater av olika form och storlek.

Sedan kommer vi till vårt baselement, Kirigami.ApplicationWindow som tillhandahåller några grundfunktioner nödvändiga för alla Kirigami-program. Det är fönstret som kommer att innehålla alla våra sidor, huvuddelen av vårt användargränssnitt.

Vi ställer sedan in fönstrets egenskap id till 'root'. Identifierare är användbara eftersom de låter oss referera till en komponent unikt, även om vi har flera av samma typ.

Vi ställer också in fönstrets egenskap title till "Hello World".

Därefter anger vi första sidan i vår sidstapel. Del flesta Kirigami-program är organiserade som en stapel av sidor, där varje sida innehåller relaterade komponenter anpassade för en viss uppgift. För närvarande låter vi det vara enkelt, och håller oss till en enda sida. pageStack är en sidstapel som initialt är tom som Kirigami.ApplicationWindow tillhandahåller, och med pageStack.initialPage: Kirigami.Page {...} ställer vi in den första sidan som presenteras när programmet laddas i en Kirigami.Page. Sidan står för allt vårt innehåll.

Slutligen inkluderar vi en Controls.Label på vår sida, som låter oss placera text på den. Vi använder anchors.centerIn: parent för att centrera vår beteckning horisontellt och vertikalt inom vårt överliggande element. I det här fallet är det överliggande elementet för Controls.Label vår Kirigami.Page. Det sista vi behöver göra är att ange texten: text: "Hello World!".

Kompilera och installera programmet

Den genererade körbara filen kirigami_hello finns i build/debug/kirigami_hello och man kan köra den direkt eller med cargo run, men den saknar en fönsterikon. För att åtgärda det installerar vi först programmet.

Kör följande:

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

Med det första kommandot söker CMake efter Kirigami och qqc2-desktop-style.

Med det andra kommandot bygger CMake målet kirigami_rust, som bara anropar cargo build --target-dir build/. Steget tar en stund att slutföra, men nästa gång det andra CMake-kommandot upprepas går det snabbare eller så behöver det inte alls kompileras.

I det tredje steget installerar CMake den körbara filen kirigami_hello i ~/.local/bin/kirigami_hello och skrivbordsfilen i ~/.local/share/applications, och en ny post med namnet "Kirigami Tutorial in Rust" visas i menyn.

Öppna menyalternativet och voilà! Nu dyker ditt allra första Kirigami-program upp framför dina ögon.

Skärmbild av det genererade Kirigami-programmet

För att köra den nya QML-applikationen i mobilläge kan man använda QT_QUICK_CONTROLS_MOBILE=1:

QT_QUICK_CONTROLS_MOBILE=1 kirigami_hello

Om du har kompilerat projektet manuellt med CMake och av någon anledning vill avinstallera projektet kan du köra:

cmake --build build/ --target uninstall