はじめに
Rustでグラフィカルユーザーインターフェース(GUI)を開発するためのライブラリはいくつかありますが、今回は特にシンプルで使いやすい「egui」について紹介します。さらに、日本語表示に対応させる方法も解説します。
eguiとは?
eguiは「イーグーイ(e-gooey)」と発音し、Rust製の即時モード(Immediate Mode)GUIライブラリです。以下のような特徴があります:
-
Pure Rust製: 100% Rustで書かれており、
unsafe
コードを含みません - クロスプラットフォーム: WebAssembly(ブラウザ)、Windows、macOS、Linuxで動作
- 即時モード: シンプルで直感的な状態管理
- 最小限の依存関係: 基本的な依存パッケージは少なく保たれています
公式サイト: https://www.egui.rs/
下記サービスでも使われているようで、注目しました
即時モードGUIとは
「保持モード(Retained Mode)」GUIでは、ウィジェットを作成し、コールバック関数を設定します。対して、eguiのような「即時モード」GUIでは、UIを毎フレーム再構築し、コードがより直線的でシンプルになります。
プロジェクトの準備
新しいRustプロジェクトを作成し、eframeを依存関係として追加します:
# 新しいプロジェクトを作成
cargo new egui_app
cd egui_app
Cargo.tomlに依存関係を追加
cargo add eframe
またはCargo.toml
に直接追加:
[dependencies]
eframe = "0.31.0" # 最新バージョンを確認してください
日本語対応した完全なコード例
以下が、日本語フォントを使用したeguiアプリケーションのコード例です:
use eframe::egui;
use egui::FontFamily;
use std::sync::Arc;
fn main() -> eframe::Result<()> {
// ウィンドウの設定
let options = eframe::NativeOptions {
viewport: egui::viewport::ViewportBuilder::default()
.with_inner_size([400.0, 300.0]),
..Default::default()
};
// アプリケーションの実行
eframe::run_native(
"My egui App",
options,
Box::new(|cc| {
// 日本語フォントの設定
setup_custom_fonts(&cc.egui_ctx);
Ok(Box::new(MyApp::default()))
}),
)
}
// フォント設定用の関数
fn setup_custom_fonts(ctx: &egui::Context) {
// フォント設定を取得
let mut fonts = egui::FontDefinitions::default();
// 日本語フォント(可変ウェイト)を追加
fonts.font_data.insert(
"noto_sans_jp".to_owned(),
egui::FontData::from_static(include_bytes!("../assets/NotoSansJP-VariableFont_wght.ttf")).into(),
);
// フォントファミリーに追加
fonts
.families
.entry(FontFamily::Proportional)
.or_default()
.insert(0, "noto_sans_jp".to_owned()); // 一番優先度高く追加
// モノスペースフォントにも日本語フォントを追加
fonts
.families
.entry(FontFamily::Monospace)
.or_default()
.push("noto_sans_jp".to_owned());
// フォント設定を適用
ctx.set_fonts(fonts);
}
// アプリケーションの状態を保持する構造体
struct MyApp {
name: String,
age: u32,
}
impl Default for MyApp {
fn default() -> Self {
Self {
name: "山田太郎".to_owned(),
age: 42,
}
}
}
// アプリケーションの描画とロジックを実装
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("My egui Application");
ui.horizontal(|ui| {
ui.label("名前: ");
ui.text_edit_singleline(&mut self.name);
});
ui.add(egui::Slider::new(&mut self.age, 0..=120).text("年齢"));
if ui.button("年齢+1").clicked() {
self.age += 1;
}
ui.label(format!("こんにちは、{}さん({}歳)", self.name, self.age));
});
}
}
実装手順の解説
1. フォントファイルの準備
まず、日本語フォントファイルを準備します:
-
プロジェクトの
assets
フォルダを作成します:mkdir -p assets
-
Google Fonts - Noto Sans JPから日本語フォントをダウンロードします。
-
ダウンロードしたZIPファイルから
NotoSansJP-VariableFont_wght.ttf
をassets
フォルダに配置します。
2. コードの解説
フォント設定関数
fn setup_custom_fonts(ctx: &egui::Context) {
// ...省略...
}
- この関数は、eguiのコンテキストにカスタムフォントを設定します。
-
include_bytes!
マクロを使ってフォントファイルをバイナリに埋め込みます。 -
.into()
メソッドでFontData
をArc<FontData>
に変換します(egui 0.31.xの要件)。
フォントファミリーへの割り当て
fonts.families
.entry(FontFamily::Proportional)
.or_default()
.insert(0, "noto_sans_jp".to_owned());
-
FontFamily::Proportional
(プロポーショナルフォント)に日本語フォントを追加します。 -
.insert(0, ...)
で優先度を最高に設定します(他のフォントより先に使われます)。
アプリケーション構造
-
MyApp
構造体でアプリケーションの状態を保持 -
eframe::App
トレイトを実装し、update
メソッドでUIを描画 -
run_native
関数でアプリケーションを起動
実行結果
これで、アプリケーションを実行すると、日本語が正しく表示されます:
実際の画面では、日本語文字がきれいに表示され、スライダーやテキスト入力欄が機能します。
まとめ
eguiを使えば、Rustで簡単にクロスプラットフォームのGUIアプリケーションを開発できます。日本語表示に対応させるためには、適切な日本語フォントを埋め込むだけで済みます。
特筆すべき点:
- 即時モードGUIの直感的なコーディングスタイル
- クロスプラットフォーム対応(デスクトップおよびWeb)
- 日本語フォントの簡単な組み込み方法
これを機に、Rustでの独自のGUIアプリケーション開発にチャレンジしてみようかなと思います!