LoginSignup
36
26

More than 1 year has passed since last update.

インストールが簡単なRuby用のGUIライブラリlibuiのバインディングを作った話

Last updated at Posted at 2020-12-25

追記

現在、LibUI上に構築された使いやすいDSL、glimmer-dsl-libui がAndy Maleh氏によって開発されました。素のLibUIで使いにくいところが大幅に改良されています。おすすめです。

はじめに

こんにちは。

今日はRuby3.0がリリースされる日です。
先日libuiというRubyでGUIを作れるGemをリリースしました。
( libui のバインディングです)
まだまだ足りない部分は多いかと思いますが記事にします。

Windows Mac Linux

背景とモチベーション

 これまでにもRubyのGUIライブラリは多数作られてきました。Ruby/TkRuby/Gtk、一世を風靡したShoes、Qt, FXRuby、ほかにもたくさん。

 しかし、Windows環境で手軽にGUIアプリケーションを作る方法が少ないという状況は続いていました。Ruby/GtkやRuby/Tkを利用する場合、TkやGTKといったツールキットのインストールが必要です。これは、初心者にとって障壁になります。また、ベテランの方でも、ユーティリティにさくっとGUIを追加して配布したいことはあると思います。この問題を解決するために、libuiというポータブルなGUIライブラリのバインディングを作成しました。

 libuiは2020/12/25時点で、Ruby界で最もインストールが簡単なGUIライブラリだと思います(たぶんね)。

libuiとは

 libuiは非常に軽量なC言語で書かれたマルチプラットフォームなGUIツールです。Rubyバインディングは、バージョン4.1に対応しています。

インストール

gem install libui

簡単なつかい方

下記に簡単な使用例を示します。

entry.gif

require 'libui'

UI = LibUI

UI.init

# ウィンドウを作成
main_window = UI.new_window('hello world', 300, 50, 1)
# ×ボタンでウィンドウを消せるようにする
UI.window_on_closing(main_window) do
  puts 'Bye Bye'
  UI.control_destroy(main_window)
  UI.quit
  0
end

# 配置用のボックス
hbox = UI.new_horizontal_box
# ボックスをウィンドウに追加
UI.window_set_child(main_window, hbox)

# 入力欄の作成
entry = UI.new_entry
# 文字が入力されたターミナルに表示
UI.entry_on_changed(entry) do
  puts UI.entry_text(entry).to_s
  $stdout.flush # リアルタイムにターミナルに表示
end
# ボックスに追加
UI.box_append(hbox, entry, 1)

# ボタン
button = UI.new_button('Button')
# ボタンが押されたら、ダイアログを出す
UI.button_on_clicked(button) do
  text = UI.entry_text(entry).to_s
  UI.msg_box(main_window, '入力した文字は次の通りです', text)
  0
end
# ボックスに追加
UI.box_append(hbox, button, 0)

# ウインドウを表示
UI.control_show(main_window)
UI.main
UI.quit

(irbやpryだとうまく実行できないのでご注意ください)

もう少し詳しいつかい方を知りたい方は、リポジトリのExamplesを見てください。

記法の一般的なルール

Cで書かれたオリジナルのlibuiと比較して、

  • メソッド名はsnake_caseです。
  • 最後の引数がnilの場合、省略できます。
  • ブロックをコールバックとして渡すことができます。
    • ブロック内で明示的に0を返してください。
    • ブロックはProcオブジェクトに変換され、最後の引数に追加されます。
    • その場合でも、最後の引数nilを省略できます。

オブジェクト指向じゃないの?

  • 現時点では、オブジェクト指向ではありません。
    • 中途半端なオブジェクト指向アプローチを提供する代わりに、そのままにしています
    • 将来的にオブジェクト指向にしていくかは現時点では未定です。

既存のlibuiバインディングとの比較

libuiには、すでにRubyのバインディングが存在します。

 しかし、このパッケージはインストールが面倒という弱点があります。libuiはこの点を解消しています。

  • C言語の関数の呼び出しに、Ruby標準ライブラリのfiddleを用いて行っています。(追加のライブラリは不要です)
  • libuiの共有ライブラリをGemの中に梱包しています。(libuiのインストールは不要です)
    • libui.so, libui.dylib, libui.dll です。
    • Gemのサイズを心配する人がいるかもしれませんがご安心ください。 全て合わせてもファイルサイズはたったの1.4MBです。Ruby/Tkと比較してもかなり軽量です。Windowsしか使わないという方は、あとからlibui.so, libui.dylibを削除しても大丈夫です。この場合、libui.dll は269Kしかありません。とても軽量です。
  • libui-rubyよりもRubyらしい記法を実現しています。特にブロック記法を用いたコールバックに対応しています。

OCRAを使って実行ファイル(EXE)を作る方法

次の3つのdllを指定する必要があります。また、念の為にfiddleを確実に含めるようにしておきます

ocra examples\control_gallery.rb        ^
  --dll ruby_builtin_dlls\libssp-0.dll  ^
  --dll ruby_builtin_dlls\libgmp-10.dll ^
  --dll ruby_builtin_dlls\libffi-7.dll  ^
  --gem-all=fiddle                      

さらに、必要に応じて次のようなオプションを追加します。詳しくはOCRAのマニュアルをご覧ください。

  --window                              ^
  --add-all-core                        ^
  --chdir-first                         ^
  --icon assets\app.ico                 ^
  --verbose                             ^
  --output out\gallery.exe

おまけ 非同期処理しなきゃならないときにはdrubyというのがあります

 RubyでGUIを伴うデスクトップアプリケーションを作るというのは、Shoesの一時的なブームを除いて、あまり流行しない印象があります。その理由の一つは、GUI側と、Rubyのロジックの非同期処理が面倒くさいからだと思います。この場合、drubyを利用するのが一つの解決策になることがあります。参考まで。

36
26
17

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
36
26