Go ISBNBookTitler

GoのFyneを使ってクロスプラットフォーム向けGUIツールを作った話

スポンサーリンク

はじめに

この記事はGo Advent Calendar 2021の20日目の記事です。

(既に25日で空き枠はもうない状態なので、空いている前の日に入れてしまいました・・・。)

 

ScanSnap等のドキュメントスキャナで自炊した、pdfやzip書籍のリネームするツール、ISBN Book Titler FyneをGo言語で作りました。

MacとWindowsで動くように作っています。(Linuxでの動作確認はできていません。)

(また、DLは準備がまだできていないので、年末に時間をとって調整して、出来次第公開しようと思います。)

Go言語を最近勉強して触りだし、勉強のアウトプットとして作りました。

まだまだ初心者レベルなので、大した内容はありませんが折角なので、実装した上での気がついた点や苦労した点、実際にFyneを使った上でのメモなどを書いてみようと思います。

 

スポンサーリンク

背景等

ベースとなるISBN Book Titlerというツールは、元々Windows向けに6~7年ほど前に作ったものです。
.NET Framework(C#)で実装されています。

ここ数年は個人開発において、Macを使う事が増え、Windows向けではなくMacでも動くようなツールにしたいと前々から思っていました。
数年前にVueやReactを使って、Electronで作ろうかと思っていましたが、最近読んだ、「Go言語ハンズオン」という書籍の勉強結果として作ってみるのも良いなぁと思い立って作ってみました。

Go言語ハンズオンの感想はこちら

 

ツールの機能

いわゆる自炊と呼ばれる、自分でスキャンした書籍を自動でリネームするツールです。

書籍の自炊といえば、富士通から発売されているScanSnapによって、ここ10年くらいでだいぶ一般化しました。

最近は電子書籍が一般化した事で、一時期ほどのブーム感はありませんが、いまだに自炊している人は多いかと思います。(私もその一人)

 

大量の書籍をスキャンした後に、1つ1つファイル名を設定していくのは結構手間がかかる作業なので、とりあえずある程度自動でリネームできたら嬉しいよねという考えで作られています。

仕組みとしては、スキャンした書籍から、裏表紙などにあるISBNコード(バーコード)を検出し、そのISBNコードから書籍情報APIで書籍情報を取得してリネームするとなっています。

PDFから画像を抜き出したり、バーコードを検出するためにGhostscriptやZBarといった外部のツールと連携しています。(要別途インストール)

設定画面(ツールのパスや書籍情報取得APIの設定)

 

ドラッグドロップでファイルをまとめて一括で変換できるといったお手軽さも売りですが、今回は使用したGUIフレームワーク側がドラッグドロップにまだ対応していないため、一旦アプリケーションを落とした上で、ツール本体(exe)に直接ドラッグドロップといった方式を採用しています。

将来的に対応されそうなので、その際には実装してみたいと考えています。(参考元)

 

スポンサーリンク

UIフレームワーク

Goのマルチプラットフォームの向けのUIフレームワークに関しては、何種類かあるものの、デファクトと呼べるようなものは無いと感じました。
(あまり調べてないのですみません。)

今年のアドベントカレンダーでちょうどGoのUIフレームワークとその特徴をまとめているものがあって、参考になりました。

GoでクロスプラットフォームGUI(2022)

 

大きく分けると2種類に分かれていて、

  • HTMLを使って表示するタイプ:Electronなどのように画面はchromiumなどのレンダリングエンジンを使用
  • Goでそのまま記述するタイプ

今回は後者であるUIフレームワークのFyneを使用して実装しています。
理由としては、単純でGo言語ハンズオンで使われていて、良さげだったからという理由です・・・。

 

苦戦したところ

Go言語自体の書き方

以前に一度AWS Lambdaの処理をGoで書くといった事をやっているので、クラスベースではなく構造体ベースな点や例外がないといった点などはあまり驚き等は無く、こういったものと慣れてきました。

ただ、実装方法はわかっても、どういう構造で実装するのが良い書き方なのかといった点が、把握ができていないというのが正直な点です。

そういった意味で1月に発売される、Goの下記の書籍は文法などが説明されている入門書とは異なる視点で学びがあるのではないかと期待しています。

 

エキスパートたちのGo言語

 

マルチプラットフォームを前提としたAPI

Go自体がマルチプラットフォームを前提としたAPIとなっているため、OSによって差がある部分などは少し苦戦しました。

具体的にはファイルパスの制御やプロセスの実行などの部分です。

Macで動かすと大丈夫だけど、Windowsに持っていって動かしてみると動かない場合などがあり、内容を確認しながら直していきました。

 

Fyneの画面制御

Fyne自体の画面の制御方法を理解するのに時間を要しました。

UIコンポーネントの種類は多く、ドキュメント自体もあるものの、細かい部分などは書いていない事が多く、GitHub上にあるサンプルのアプリを動かしつつ、ソースコードを見ながら使い方を確認していくといった事が必要でした。

まだまだ発展途上ということもあり、ある程度完成された(枯れた)UIフレームワークであればある機能が無かったり、実装が大変だったりといった事があります。

以降に、個人的にFyneで苦労した点やメモなどをまとめています。

 

Fyneでの実装メモ

Tableの実装

Tableを用いて一覧を表示する事ができます。ヘッダー機能が無かったり、各カラムの幅を表示内容に合わせて自分で制御しないといけないなど、まだまだ発展途上感はあります。

コレクションを渡せばいい感じで一覧表示してくれる便利なコンポーネント群に慣れてしまった自分には、かなり衝撃的でした。
(ヘッダー自体を通常のレコードとして1行目に入れるといった方法で実装。ただし、ヘッダ固定はできない。)

 

実際の画面:一行目のヘッダっぽいのも通常のレコードで実装

 

UI要素の表示や更新方法

Fyne自体はよくある画面要素を直接操作する方法と、変数とリンクして使用するデータバインディングの両方に対応しています。

今回は、極力データバインディングを使用して実装しました。

 

画面を触る方法(v1~

v1からある画面インスタンスを直接触る方法です。

ボタンを押下した時に、テキスト入力(Entry)のTextフィールドから値を取得して、ラベルのSetTextメソッドを使用して値を設定しています。

 

 

バインディングを使用する(v2~

v2からはバインディングを使用した操作ができます。(v1同様に画面インスタンスを触ることも可能)

string型の2つのbindingを作成し、それをEntryとLabelに渡します。

渡す際にはNewXXXWtihDataというコンストラクタが用意されているのでそちらを使用します。

bindingには、GetとSetというメソッドが用意されているのでそれを使用して値の取得および設定をすれば画面側にも反映されるようになります。

もちろん、構造体のメンバに関してもバインディングは可能です。

 

日本語への対応

現時点ではFyneはデフォルトでは日本語に対応しておらず、そのまま表示すると文字化けます。

一番お手軽な解決方法として、環境変数にフォントを指定するといった事で解決できるようです。

ですが、自分自身しか使わないならばまだしも、配布等を行う場合には使うのは難しい方法になります。

下記が参考になりますが、フォントファイルを用意してリソースとしてバンドルするといった方法で解決できました。

Go + Fyne で GUI アプリケーション(Fyne についてのメモ)

フォントファイル(ttf)を用意して、下記のようなコマンドでバンドルする事ができます。

今回はM+フォントを利用しています。

 

Fyneにはカスタムテーマを設定する方法があり、そこでフォントの変更ができるようになるので、先程のバンドルしたリソースのフォントを返すようにします。

 

まとめ

簡単にですが、GoのUIフレームワークであるFyneを使って作ったツールの実装時の話をしてみました。

まだまだGo言語を触り始めたばかりなので、もっと触って慣れていきたいと思っています。

ツール自体もまだまだ機能追加などをやりつつ、次はWEBアプリなどにも挑戦してみたいと思います。

 

-Go, ISBNBookTitler

© 2022 nobu blog Powered by AFFINGER5