mieki256's diary



2026/02/25(水) [n年前の日記]

#1 [nim] wNimについて勉強中

Nim言語でWindows用のGUIアプリを作成できるライブラリ、wNim について勉強中。

環境は Windows11 x64 25H2 + Nim 2.0.6 x64。

wNimが利用できるNimのバージョンについて :

wNim が Nim 2.2.6 や 2.2.8 で動かなくて、Nim 2.0.6 なら動くのは分かったけれど。Nim 2.0.x にはどんなバージョンがあるのか確認してみたら、2.0.6 以降は 2.0.8, 2.0.10, 2.0.12, 2.0.14, 2.0.16 がある模様。

2.0.16 でも wNim が利用できないものか。choosenim 2.0.xx と打って試してみた。

  • Nim 2.0.8 までなら wNim を使ってもコンパイルエラーが出なかったし動いてくれた。
  • Nim 2.0.10, 2.0.12, 2.0.14, 2.0.16 はコンパイルエラーが出て動かなかった。

2026/02/25現在、wNim を使いたいなら Nim 2.0.8 までに留めておくしかなさそう…。

wNim利用時のコンパイル指定 :

今のところ以下の指定をしてコンパイルしてる。

nim c -d:release -d:strip --opt:size --app:gui hellownim2.nim

  • -d:release はリリース用ビルド。Cコンパイラに最適化オプションを渡すので、出来上がった実行形式バイナリの処理速度が速くなる。これをつけないと処理速度がめっちゃ遅くなる。と言われてる。
  • -d:strip は、デバッグ情報の削除。ファイルサイズが小さくなってくれる。
  • --opt:size は、実行速度よりもファイルサイズ削減を優先せよ、という指定。
  • --app:gui は、GUIアプリを作成せよ、という指定。エクスプローラ等でダブルクリックして実行した際にコマンドプロンプトが出なくなる

以下の記事の解説が参考になった。ありがたや。

_Nim 最適化の方法と--optオプション (改訂版) Nim - Qiita

wNimのレイアウトについて :

wNim の部品レイアウトには、VFL (Visual Format Language) なる記述フォーマットを使うらしい。Apple が提案したやり方…なのだろうか? 違うのかな?

_Auto Layout Guide: Visual Format Language
_VFLを使ってみよう
_autolayout

wNim はそのやり方にインスパイアされて、似たような感じの記述方法を盛り込んでみた、ということらしい。一応分かった範囲でメモしておく。

wNim の場合、基本的には「H:」で横方向の配置指定をして、「V:」で縦方向の配置指定をしていく。

「H:」と「V:」を別々に記述する場合、
「横方向については、この部品はココに配置される」
「縦方向については、この部品はココに配置される」
という書き方になるので、部品名が二度出現することになる。

例えば以下のサンプルの場合、ラベル1、ラベル2、ボタンが、ずらりと縦方向に並ぶ配置になるわけだけど…。

hellownim2_ss01.png


_hellownim2.nim
import wNim

# アプリケーションの基盤準備

let app = App() # wNimアプリケーションのインスタンス作成
let frame = Frame(title = "Hello wNim") # メインウィンドウ(枠)の作成
let panel = Panel(frame) # ウィンドウ上の土台となるパネルを作成

# コントロール(部品)の作成

let sText1 = StaticText(panel, label = "Hello World")

# フォント設定: サイズ28, サンセリフ体(Swiss), 太字(Bold)
sText1.font = Font(28, family = wFontFamilySwiss, weight = wFontWeightBold)

# テキストの内容に合わせてコントロール自体のサイズを自動調整
sText1.fit()

let sText2 = StaticText(panel, label = "Hello wNim")
sText2.font = Font(16, family = wFontFamilySwiss, weight = wFontWeightBold)
sText2.fit()

let btn = Button(panel, label = "Click Me!")

# レイアウト定義(AutoLayout)
proc layout() =
  # autolayout: 文字列で相対的な位置関係を記述する機能
  # | : 親要素(panel)の端
  # ~ : 柔軟なスペース(スプリングのようなもの)
  # [element] : 配置するコントロール
  # (n) : サイズ指定(ピクセル)
  panel.autolayout """
    H:|~[sText1]~|      # 水平方向(H): 左右に伸縮空間を入れ、テキストを中央寄せ
    H:|~[sText2]~|
    H:|~[btn(200)]~|    # 水平方向(H): ボタン幅を200固定にし、左右に空間を入れて中央寄せ
    V:|~[sText1]~[sText2]~[btn(50)]~| # 垂直方向(V): 上下と間に空間を入れ、ボタン高さを50に固定
  """

# イベントハンドラ(動作)の定義

# パネルのサイズが変更された時にレイアウトを再計算する
panel.wEvent_Size do():
  layout()

# ボタンがクリックされた時の処理
btn.wEvent_Button do():
  # メッセージダイアログを生成して表示(.display() はモーダル表示)
  MessageDialog(frame, "Hello", caption = "MessageDialog").display()

# 5. アプリの起動準備
layout() # 初回起動時の配置計算
frame.center() # 画面の中央にウィンドウを表示
frame.show() # ウィンドウを可視化
app.mainLoop() # イベントループ開始(終了まで待機)


レイアウトを指定しているのは、proc layout() = のあたり。

proc layout() =
  panel.autolayout """
    H:|~[sText1]~|
    H:|~[sText2]~|
    H:|~[btn(200)]~|
    V:|~[sText1]~[sText2]~[btn(50)]~|
  """

コメント付きなら以下。AI(Google Gemini)にコメントをつけてもらった。

# レイアウト定義(AutoLayout)
proc layout() =
  # autolayout: 文字列で相対的な位置関係を記述する機能
  # | : 親要素(panel)の端
  # ~ : 柔軟なスペース(スプリングのようなもの)
  # [element] : 配置するコントロール
  # (n) : サイズ指定(ピクセル)
  panel.autolayout """
    H:|~[sText1]~|      # 水平方向(H): 左右に伸縮空間を入れ、テキストを中央寄せ
    H:|~[sText2]~|
    H:|~[btn(200)]~|    # 水平方向(H): ボタン幅を200固定にし、左右に空間を入れて中央寄せ
    V:|~[sText1]~[sText2]~[btn(50)]~| # 垂直方向(V): 上下と間に空間を入れ、ボタン高さを50に固定
  """


  • 部品間に隙間を入れたい場合は「-」か「~」が使える。「-」は固定スペース。「~」は伸縮スペース。
  • 「|」は、親ウインドウの境界の端を示している。例えば、「H:|-[部品A]」と書いてあれば、「横方向の指定 : 親ウインドウの左端から、固定スペースが入って、部品Aが配置される」という意味になる。
  • 「[部品名]」という記述が出現するけれど、「[ ]」は列相当になるのかな…。その列の中にはこの部品が入るぞ、という指定だと思われる。
  • その列(or 行)の中に複数の部品が入る時は、「[部品A,部品B]」という記述になる時もある。
  • 部品名のすぐ後ろに「[部品A(100)]」等、括弧と数値が付く時がある。これは横幅、もしくは縦幅を指定してる。単位はドット。「H:」の指定行で書けば横幅の指定になり、「V:」の指定行で書けば縦幅の指定になる。数値の代わりに部品名を書いてもいい。例えば「[部品A(部品B)]」と書けば、部品Aの幅は部品Bの幅と同じにする、という意味になる。


wNim の examples/ の中の autolayoutEditor.nim をコンパイルして、autolayoutEditor.exe を作って実行すると、こういうVFLの記述をすればこういうレイアウトになる、というサンプルがいくつか見れるようになるので、多少は参考になりそう。

autolayoutEditor_ss01.png

余談。VFLは分かりづらい気がする :

PySimpleGUI あたりを触ってしまった後では、VFL って分かりづらいなと…。最初に目にしたときはチンプンカンプンだった…。

PySimpleGUI のように、二次元配列で部品名を記述してテーブルレイアウトで済ませてはダメなのだろうか? いやまあ、部品同士がずれるような配置はテーブルレイアウトだとちょっとややこしくなるけれど、ほとんどのGUIアプリはテーブルレイアウトで対応できそうな気も…。

どんな文書もExcelで作ってしまう人が出現してしまうぐらいに、テーブルレイアウトって初心者でも分かりやすい上に意外と万能、なのではないかなあ…。GUI部品のレイアウトって再利用しない系の情報だろうから、万が一ネ申Excelっぽくなっても問題無さそうな…。

余談その2。AIは頼りにならない :

wNim関係の質問をAIにしてみると嘘ばかり返ってくる…。妙な部分を逐一指摘していったら、とうとうAIが「サンプルソースを確認するのが確実です」と言ってきた…。たしかにその通りだけど、AIまで匙を投げたか…。ドキュメントやソースコードの量がまだ全然少なくて学習が不十分ということなんだろう…。

#2 [nim] NiGuiを試用

Nim言語でGUIアプリを作成できるライブラリとして、NiGui というものがあるらしい。

wNim はWindows専用だったけど、この NiGui はクロスプラットフォーム対応 ―― Windows/Linux/Mac でも使えるのだとか。

_simonkrauter/NiGui: Cross-platform desktop GUI toolkit written in Nim

気になったので試用してみることにした。環境は Windows11 x64 25H2 + Nim 2.2.8 x64。

インストール :

nimble install nigui

使ってみた :

wNim は Nim のバージョンを 1.6.20、2.0.0、2.0.6、2.0.8 等に落とさないと使えなかったけれど、NiGui は Nim 2.2.8 でもあっさり使えてしまった。

サンプルは以下。

_hellonigui.nim
import nigui

app.init()
let win = newWindow("Hello NiGui")
win.width = 400.scaleToDpi
win.height = 300.scaleToDpi

win.iconPath = "example_01_basic_app.png"

let con = newLayoutContainer(Layout_Vertical)
win.add(con)

let lbl = newLabel("Hello NiGui.")
lbl.fontSize = 28
lbl.fontFamily = "Consolas"
lbl.width = 350
lbl.height = 100
con.add(lbl)

let btn = newButton("Button 1")
con.add(btn)

let exitBtn = newButton("Quit")
con.add(exitBtn)

btn.onClick = proc(event: ClickEvent) =
  win.alert("Hello. This is a simple message box.")

exitBtn.onClick = proc(event: ClickEvent) =
  app.quit()

win.show()
app.run()

コンパイルは以下。
nim c -d:release -d:strip --opt:size --app:gui hellonigui.nim

hellonigui.exe が生成された。実行もできた。

hellonigui_s01.png

雑感 :

wNim に比べると圧倒的に分かりやすい気がする…。しかも、現行版 Nim 2.2.8 でもコンパイルエラーを出さずに使えるし。さらにクロスプラットフォーム対応。もうこれでいいんじゃないか…?

ただ、シンプルな仕様にした分、制限もあるようで…。

「ボタンの背景色を変えることなどはできない」
「見た目を変えたいならカスタムコントロールを作れ。自前で描画処理を書くのが面倒だけど」
「そういう時は別のGUIライブラリを検討したほうがいい」

といった言及を公式サイト上で見かけた。

見た目にはこだわらず、質実剛健、シンプルイズベストで作るなら、このライブラリは実にイイ感じかもしれない。

というか、wNim を触って、やれコンパイルができないだの、レイアウト方法が分からないだので悩んでいたわけだけど、NiGui を触ったらどれもサクサクと動作確認ができて、wNim を試用していたことがちょっと馬鹿らしくなってきて…。ひとまず何かしら動いてくれないと話にならないわけで、動かせる状態にするだけでもスンナリ行かないライブラリはちょっとなあ…。

気になる点 :

ラベルを表示してみたら、ウインドウが表示されてからラベルが表示されるまで、ワンテンポ遅れる感じが…。何か計算してるのだろうか…。それともリトライ処理でもしてるのだろうか…。

#3 [anime] 「シン・エヴァンゲリオン劇場版」が地上波放送されていたらしい

録画していたTVアニメを消化していたら「シンエヴァを明日放送するよ!」と番宣映像が…。知らなかった。もう放送日過ぎちゃってるがな…。完全に見逃した…。ショック…。

ま、いっか。どうしても見たかったらお金を払ってでも見るよな…。自分の中でそこまでする気はないということは、心のどこかでこれは見なくてもいい作品とうっすら思ってるのかもしれない…。いや、たまたま何かの拍子に偶然目にして「この映画…すげえ…とんでもねえな…」と思う時も結構あるのだけど…。期待度と作品の出来不出来は全く別と言うか…。

個人的にエヴァ新劇場版は、もう何をやってるのかさっぱりわからない印象で…。1作目はTV版を踏襲してたからまだ流れがうっすら理解できたけど、2作目、3作目は頭の中が「???」だらけに…。ついていけない…。いや、考えてみたら旧劇場版も「???」だった気がしてきた。「映像凄いな…。でも状況がさっぱり分からん…」と…。凄い映像を見れてるんだから自分は損をしてないはずだ、と必死に思い込もうとしていたような気もする…。

新作が出てくるらしいけど、きっとそれも自分が見たら何が何だかさっぱり分からないのだろう…。ファンの人達は凄い…。色々なメディアから補足情報を探してきて、どうにか補完して理解してるんだろう…。根気が要る作業だろうなあ…。

#4 [nitijyou] 親父さんが入院

詳細はGRPでメモ。

以上、1 日分です。

過去ログ表示

Prev - 2026/02 -
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

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project