1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rust】icedでデスクトップアプリケーションを作る

Posted at

はじめに

こんにちは、梅雨です。

今回は iced クレートを用いてデスクトップアプリケーションを作る方法を解説していきたいと思います。

iced はまだメジャーバージョンがリリースされていないため、マイナーアップデートによって大きく変更が加わります。この記事では最新のバージョンを用いて、簡単なカウントアプリを作成していきます。

iced とは?

iced とは、Rust のクロスプラットフォーム GUI ライブラリであり、デスクトップや Web 向けのアプリケーションを簡単に作成できます。

環境構築

プロジェクトはCargoを用いて作成します。

$ cargo new iced-demo
$ cd iced-demo

iced をインストール。

$ cargo add iced

Cargo.tomlを確認すると、icedの0.13.1が入っています。(2024/12/11現在の最新バージョン)

Cargo.toml
[package]
name = "iced-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
iced = "0.13.1"

プロジェクトのビルド & 実行を行い、Hello, world! が出力されることを確認しましょう。

$ cargo run
# --- 中略 ---
Hello, world!

アプリケーションの作成

iced は Elm という GUI 開発向けプログラミング言語にインスピレーションを受けており、The Elm Architecture に基づいた構成となっています。

Elm は以下の3つの要素をコアとしています。

  • Model: アプリケーションの状態
  • View: 各状態に対応する見た目
  • Update: メッセージに基づいて状態を更新するロジック

簡単にいうとステートによって見た目の制御を行う構成であり、React 等のモダンなフロントエンドライブラリを用いたことがある人にはかなりわかりやすいと思います。

まずはステート(=Model)を用意しましょう。今回必要なステートはvalueで、型はi32としました。Rustには数値の型がたくさんあり、符号の有無やビット数を細かく指定できます。

大きさ 符号付き 符号なし
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
main.rs
struct Counter {
  value: i32,
}

続いてメッセージを用意します。メッセージとはステートに変化を加えるアクションのようなもので、今回は足し引きを行えるように IncrementDecrement の二つのメッセージを定義しました。

main.rs
enum Message {
  Increment,
  Decrement,
}

ステートとメッセージが用意できたら、これらを紐づけるロジック(=Update)を記述していきましょう。引数にはステートへの参照とメッセージをとります。

main.rs
fn update(counter: &mut Counter, message: Message) {
  match message {
    Message::Increment => {
      counter.value += 1;
    }
    Message::Decrement => {
      counter.value -= 1;
    }
  }
}

最後に見た目(=View)を記述していきます。iced にはさまざまなウィジェットが用意されており、例えばcolumnを使うと要素を縦並びにすることができます。

見た目はステートの変更によって自動で更新されるので、見た目自体を更新するようなコードは必要ありません。

main.rs
use iced::widget::{button, column, text};
use iced::Element;

fn view(counter: &Counter) -> Element<Message> {
  return column![
    button("+").on_press(Message::Increment),
    text(counter.value),
    button("-").on_press(Message::Decrement)
  ]
  .into();
}

これでアプリケーションの準備が終わりました。main 関数の中にウィンドウを起動するコードを書きます。

main.rs
fn main() {
  iced::run("Count App", update, view).unwrap();
}

このとき、CounterMessage に対し、以下のトレートを実装する必要があります。

main.rs
+ #[derive(Default)]
struct Counter {
  value: u32,
}

+ #[derive(Clone, Debug)]
enum Message {
  Increment,
  Decrement,
}

以上で実装は完了です。今までのコードはこのようになっています。

main.rs
use iced::widget::{button, column, text};
use iced::Element;

#[derive(Default)]
struct Counter {
  value: u32,
}

#[derive(Clone, Debug)]
enum Message {
  Increment,
  Decrement,
}

fn update(counter: &mut Counter, message: Message) {
  match message {
    Message::Increment => {
      counter.value += 1;
    }
    Message::Decrement => {
      counter.value -= 1;
    }
  }
}

fn view(counter: &Counter) -> Element<Message> {
  return column![
    button("+").on_press(Message::Increment),
    text(counter.value),
    button("-").on_press(Message::Decrement)
  ]
  .into();
}

fn main() {
  iced::run("Count App", update, view).unwrap();
}

アプリケーションを実行します。

$ cargo run

ウィンドウが立ち上がり、カウントアプリが表示されていれば成功です。

おわりに

今回は iced を用いて簡単なカウントアプリを作成しました。

発展的なアプリケーションも基本的には今回と同じような流れて作成することができるので、興味のある方はぜひ挑戦してみてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?