Help us understand the problem. What is going on with this article?

RustでGUI 〜iced編〜

プログラム全体はgithubのogata-k/GUI_cmp/example_icedをご覧ください。

iced

今回使用するバージョンは0.1.0-betaです。

どんなクレートか

icedはバージョンにbetaとあるようにまだまだ開発中のGUIライブラリです。READMEによるとElmにインスパイアされて作られたクロスプラットフォーム向けのライブラリです。Elmを参考にしているだけあってコードの見た目もElmに見えます。
珍しいことにWebアプリもサポートしてるとのことです。さらに各種基本的なレンダーライブラリの対応や非同期も対応しています。

コード

main.rs
use iced::{Sandbox, Element, Button, Column, Text, Settings, Container, Length, Align, HorizontalAlignment, Color, Background, button};
use iced::settings::Window;

pub fn main() {
    Counter::run(Settings {
        window: Window {
            size: (300, 300), // (x, y)
            resizable: false,
        }
    })
}

// state
struct Counter {
    // counter value
    value: i32,

    // state of the two buttons
    increment_button: button::State,
    reset_button: button::State,
}

// message
#[derive(Debug, Clone, Copy)]
pub enum Message {
    Increment,
    Reset,
}

impl Sandbox for Counter {
    type Message = Message;

    fn new() -> Self {
        Counter {
            value: 0,
            increment_button: button::State::default(),
            reset_button: button::State::default(),
        }
    }

    fn title(&self) -> String {
        String::from("count up")
    }

    // update
    fn update(&mut self, message: Message) {
        match message {
            Message::Increment => {
                self.value += 1;
            }
            Message::Reset => {
                self.value = 0;
            }
        }
    }

    // view logic
    fn view(&mut self) -> Element<Message> {
        Container::new(
            Column::new()
                .push(
                    Button::new(&mut self.increment_button, Text::new("+1"))
                        .on_press(Message::Increment)
                        .border_radius(5)
                        .background(Background::Color(Color{r: 0.8, g: 0.8, b: 0.8, a: 1.})),
                )
                .push(
                    Text::new(self.value.to_string()).size(50).horizontal_alignment(HorizontalAlignment::Center),
                )
                .push(
                    Button::new(&mut self.reset_button, Text::new("reset"))
                        .on_press(Message::Reset),
                )
                .align_items(Align::Center)
        )
            .width(Length::Fill)
            .center_x()
            .height(Length::Fill)
            .center_y()
            .into()
    }
}

iced.png

コードの説明

main関数ではGUIのおおもととなるWindowの設定を元にアプリを起動するところだけを請け負います。
次に状態のモデルとなるCounterモデルです。今回はカウント値、カウントアップボタン、リセットボタンの状態を表現しています。
次に状態の変更を通知するときに通知するイベントメッセージのMessage列挙体です。今回は増加とリセットを表現しています。
そしてSandboxトレイトを実装することで描画と更新処理を実装します。Applicationというトレイトもあるのですが、こちらは非同期を扱うときのトレイトとなります。描画はview関数で定義します。少しレイアウトの定義関数に癖がある気がしますが、よくある記述で書くことができます。
更新処理のupdate関数は状態モデルを更新する処理だけを行います。

所感

まだまだ実用には向かず未成熟な感じが強いですが、触ってみた限り完全にElmですね。モデルやメッセージが肥大化しそうな予感はありますが、慣れるとElmアーキテクチャの方がGUIは表記しやすいかもしれませんね。

まとめ

まだまだ未成熟なライブラリですが、実用的になればRustでGUIと言ったらこれ!といえるGUIライブラリの一つになりそうな予感がします。

ogata-k
RustとHaskellとCLIツールと処理系好き。いつかRustで仕事をしてみたい初心者。 Twitterは@ogtkzkです。
https://ogata-k.hatenablog.com/about
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした