M.Hiroi's Home Page

Lightweigth Language

お気楽 Ruby/Tk 超入門

[ PrevPage | Ruby | NextPage ]

はじめに

Ruby はシンプルでわかりやすいオブジェクト指向スクリプト言語です。シンプルといっても簡易言語ではありません。オブジェクト指向だけではなく、モジュール、例外処理、マルチスレッドといった高度な機能を備えていて、大規模なソフトウェアでも開発できる汎用のプログラミング言語として、さまざまな分野で使われています。

GUI (Graphical User Interface) に対応したアプリケーションの作成もそのひとつです。GUI アプリケーションの開発は、CLI (Command Line Interface) 用のプログラムを作るよりも相当の労力を必要とします。さらに、GUI はユーザーの使い勝手に直結しているため、プログラムの改良を頻繁に行うことがあります。このため、GUI の開発は簡単にプログラムの修正と実行が行えるスクリプト言語が適しているといわれています。

GUI 用のスクリプト言語で有名なのが Tcl/Tk です。Tcl は Tool Command Language の略で、もともとはアプリケーションに組み込むためのコマンド言語として設計されたのですが、GUI の部品を集めた Tk (Tool Kit) と組み合わせることで、Tcl/Tk だけで GUI アプリケーションを簡単に作ることができるようになりました。特に Tk の人気はとても高く、自分の好みの言語に Tk を移植する試みが行われました。Ruby/Tk もそのひとつです。他には、Python/Tkinter や Perl/Tk (Tkx) などが有名です。

本ページでは、簡単なプログラムを作りながら Ruby/Tk の使い方を説明していく予定です。とりあえず、Tcl/Tk お気楽 GUI プログラミング入門 と同じ例題を Ruby/Tk で作ってみようと思います。たいしたことはできませんが、よろしければお付き合いくださいませ。

●インストール

最初に Ruby をインストールしてください。Debian (Ubuntu) 系 OS の場合、次のコマンドで簡単にインストールすることができます。

sudo apt install ruby

M.Hiroi の環境 (Ubunts 22.04 LTS, WSL2 + WSLg, Windows 10) では version 3.0 がインストールされます。次に、Ruby/Tk に必要なライブラリ tk と Tcl/Tk をインストールします。Tcl/Tk は次のコマンドでインストールすることができます。

sudo apt install tcl tk

M.Hiroi の環境では Tcl/Tk 8.6 がインストールされます。Ruby のライブラリ tk は標準で同梱されていないので、gem を使ってインストールします。その前に、必要となる development files をインストールします。

sudo apt install ruby-dev tcl8.6-dev tk8.6-dev

最後に次のコマンドで tk をインストールします。

sudo gem install tk

tcl.h (tk.h) や Tcl/Tk のライブラリが見つからないでインストールに失敗する場合は、オプションでインストール先のディレクトリを指定します。参考 URL によると、次に示すシェルスクリプトを実行するとよいそうです。

リスト : ライブラリ tk のインストール

sudo gem install tk -- --with-tcltkversion=8.6 \
--with-tcl-lib=/usr/lib/x86_64-linux-gnu \
--with-tk-lib=/usr/lib/x86_64-linux-gnu \
--with-tcl-include=/usr/include/tcl8.6 \
--with-tk-include=/usr/include/tcl8.6 \
--enable-pthread

M.Hiroi の環境では、これで Ruby/Tk をインストールすることができました。環境によっては、他にも必要となるファイルがあるかもしれません。インストールに失敗したときは、エラーメッセージを読んで、必要なパッケージをインストールしてください。

●日本語フォント

ところで、WSL 用の Ubuntu-22.04 には日本語フォントがインストールされていません。昔の Ubuntu は日本語フォントに Takao フォントが用いられてきましたが、Ubuntu 18.04 からは Noto フォントになりました。Noto Sans CJK JP がゴシック体、Noto Serif CJK JP が明朝体になります。

これらのフォントは apt で簡単にインストールすることができます。

sudo apt install fonts-not-cjk

もう一つ方法があって、WSL から Windows のフォントを利用することもできます。フォントのインストールは次のページが参考になると思います。

  1. Windows11 WSL2 & WSLg Ubuntu の初期設定, (hiro20180901 さん)
  2. How to install fonts on Linux, (妹尾 賢 さん)

M.Hiroi は Windows に Noto フォントをインストールしてあるので、1 の方法を使わせてもらいました。有益な情報を公開されてる作者様に感謝いたします。

●フォントの優先順位

WSL 用の Ubuntu 22.04 で Windows 側のフォントを使用すると、選択されるフォントは次のようになります。

$ fc-match
msgothic.ttc: "MS ゴシック" "標準"
$ fc-match sans
msgothic.ttc: "MS ゴシック" "標準"
$ fc-match serif
msmincho.ttc: "MS 明朝" "標準"
$ fc-match mono
msgothic.ttc: "MS ゴシック" "標準"

Linux のフォントはライブラリ fontconfig を使って管理されています。ユーザーがフォントの優先順位を変更するときは、fontconfig の設定ファイル ~/.config/fontconfig/fonts.conf で行うことができるようです。詳しい説明は fonts.conf のドキュメント (man fonts-conf) や下記 URL をお読みください。

  1. fonts-conf, (ドキュメントの HTML 版)
  2. フォント設定 - ArchWiki
  3. フォント設定/サンプル - ArchWiki
  4. manjaro linux の日本語フォントを直す - 雑記帳, (にゃおみんさん)

M.Hiroi は URL 3, 4 を参考に、fonts.conf を下記のように定義したところ、設定を Noto フォントに変更することができました。

リスト : fonts.conf

<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>

<!-- Default font (no fc-match pattern) -->
 <match>
  <edit mode="prepend" name="family">
   <string>Noto Sans CJK JP</string>
  </edit>
 </match>

<!-- Default font for the ja_JP locale (no fc-match pattern) -->
 <match>
  <test compare="contains" name="lang">
   <string>ja</string>
  </test>
  <edit mode="prepend" name="family">
   <string>Noto Sans CJK JP</string>
  </edit>
 </match>

<!-- Default sans-serif font -->
 <match target="pattern">
   <test qual="any" name="family"><string>sans-serif</string></test>
   <edit name="family" mode="prepend" binding="same"><string>Noto Sans CJK JP</string>  </edit>
 </match>

<!-- Default serif fonts -->
 <match target="pattern">
   <test qual="any" name="family"><string>serif</string></test>
   <edit name="family" mode="prepend" binding="same"><string>Noto Serif CJK JP</string>  </edit>
 </match>

<!-- Default monospace fonts -->
 <match target="pattern">
   <test qual="any" name="family"><string>monospace</string></test>
   <edit name="family" mode="prepend" binding="same"><string>Noto Sans Mono CJK JP</string></edit>
 </match>
</fontconfig>
$ fc-match
NotoSansCJKjp-Regular.otf: "Noto Sans CJK JP" "Regular"
$ fc-match sans
NotoSansCJKjp-Regular.otf: "Noto Sans CJK JP" "Regular"
$ fc-match serif
NotoSerifCJKjp-Regular.otf: "Noto Serif CJK JP" "Regular"
$ fc-match mono
NotoSansMonoCJKjp-Regular.otf: "Noto Sans Mono CJK JP" "Regular"

●参考 URL


初版 2016 年 8 月 28 日
改訂 2019 年 4 月 14 日
改訂二版 2023 年 2 月 11 日

Ruby/Tk の基礎知識

●イベント駆動方式

GUI アプリケーションの場合、ユーザーからの入力やシステムの状態変化など、ある出来事をきっかけにプログラムが実行されます。この出来事を「イベント(event)」といい、イベントをきっかけにしてプログラムが起動されることを「イベントドリブン (eventdriven)」とか「イベント駆動」といいます。イベントドリブン型のアプリケーションは、一般に次のようなメインルーチンを持っています。

  1. 初期化
  2. イベントを取得する
  3. イベントの種類に応じて処理を振り分ける
  4. 2 に戻る

2 から 4 を「イベントループ」と呼び、アプリケーションはユーザーからの入力などのイベントを待ちます。そして、3 の処理に対応する機能が「バインディング(binding)」です。バインディングは、ウィンドウでイベントが発生したときに、それに応じて定義したプログラムを実行します。このプログラムを「イベントハンドラ」とか「コールバック関数」と呼びます。

GUI アプリケーションとしての最低限の機能は Ruby/Tk が面倒を見てくれるので、私達はアプリケーション固有の処理をプログラミングするだけで済みます。

●Ruby/Tk で必要な手順

Ruby/Tk で GUI アプリケーションを作る場合、次のような手順が必要になります。

  1. トップレベルのウィンドウ (メインウィンドウ) を作る。
  2. ウィジェットを設定してウィンドウに配置する。
  3. イベントループを開始してユーザーからの要求 (イベント) を処理する。

このほかに、必要に応じてコールバック関数を作成します。Tcl/Tk の場合、1 と 3 の処理はプログラムする必要はありませんが、Ruby/Tk では 2 と 3 を自分でプログラムする必要があります。

それでは実際にプログラムを作ってみましょう。ボタンをひとつ表示します。

リスト : ボタンの表示

require 'tk'

button = TkButton.new(text: "Hello, Ruby/Tk")
button.pack

Tk.mainloop

最初にモジュール tk をロードしてください。次に、メインウィンドウを作成しますが、Ruby/Tk では自動的に作成されるので、私たちがプログラムする必要はありません。次にボタンを作ります。Tk では GUI 用の部品のことを「ウィジェット (widget)」と呼びます。Tk にはたくさんのウィジェットが用意されていて、それをウィンドウに配置することで簡単に GUI アプリケーションを作成することができます。

Ruby/Tk の場合、ウィジェットに対応するクラスが用意されていて、名前は Tk + ウィジェット名 または Tk::ウィジェット名 になります。ボタン (Button) を作る場合、TkButton.new() または Tk::Button.new() でボタンのオブジェクトを生成します。引数 text: 'Hello, Ruby/Tk' はボタンに表示されるテキストを指定します。name: value は :name => value と同じで、Ruby ver 1.9 から導入された表記法です。

この段階では、ボタンはまだ配置されていません。ボタンの配置はメソッド pack で行います。Tk の場合、ウィジェットの配置はジオメトリマネージャが行います。3 種類のマネージャがあって、pack はそのうちのひとつです。button.pack が実行されると、ウィンドウにボタンが配置されます。最後にメソッド mainloop() を呼び出して、イベントループを開始します。

簡単なプログラムですが、Ruby/Tk で GUI アプリケーションを作る場合の基本的な構造を表しています。あとは、イベントに対応するコールバック関数を作ります。この例題ではボタンを表示しただけですが、押したときの動作をプログラムすることができます。

Hello, Ruby/Tk Ruby/Tk のウィンドウ

●ウィジェットの種類

Ruby/Tk に用意されている主なウィジェットを表に示します。

表 : Tk に用意されている主なウィジェット
種類名前概要
フレームFrameウィジェットを格納する枠組みを作る
ラベルLabel文字列やイメージを表示する
メッセージMessage複数行の文字列を表示する
ボタンButtonボタンを作る
ラジオボタンRadiobuttonラジオボタンを作る
チェックボタンCheckbuttonチェックボタンを作る
リストボックスListboxリストボックスを作る
スクロールバーScrollbarスクロールバーを作る
スケールScaleスケールを作る
エントリーEntry1 行の文字列の入力と編集
メニューMenuメニューを作る
メニューボタンMenubuttonメニューボタンを作る
ビットマップBitmapビットマップを作る
キャンバスCanvasキャンバスを作る
テキストTextテキストの入力と編集
ラベルフレームLabelFrameラベル付きフレーム
スピンボックスSpinboxスピンボックスを作る
ペインウィンドウPanedWindowペインウィンドウを作る

なかにはあまり見かけないものもありますが、大部分はお馴染みのウィジェットだと思います。Tk 8.5 からは Ttk Widget と呼ばれる新しいウィジェットが追加されました。Ttk Widget を使うとテーマの変更で GUI の見栄えを切り替えることができます。Ttk Widget はあとで取り上げる予定です。

ウィジェットは次の形式で生成します。

widget = widgetClass.new(parent, args, ..., option: value, ...) { ... }

widgetClass は Tk + 名前 になります。この場合、変数 Tk.default_widget_set で Tk と Ttk を切り替えることができます。値が :Tk の場合は Tk のウィジェットが使用され、:Ttk の場合は Ttk のウィジェットが使用されます。デフォルト値は :Tk です。

なお、widgetClass を Tk::名前 とすると Tk のウィジェットに、Ttk::名前 とすると Ttk のウィジェットになります。本ページでは Tk + 名前 で widgetClass を記述することにします。

parent は widget を配置するウィンドウやウィジェットのオブジェクトを指定します。省略するか nil を渡すと、widget はメインウィンドウに配置されます。args はメソッド固有の引数です。ごく一部のメソッドでは、この引数が必要になることがあります。返り値は生成したウィジェットのオブジェクトです。メインウィンドウもウィジェットのひとつです。

ウィジェットにはユーザーがデータを設定することができます。これを「オプション」または「属性」といいます。Ruby/Tk では属性と呼ぶことが多いようです。本ページでは Tcl/Tk に合わせてオプションと呼ぶことにします。なお、メソッド new はブロックを受け取ることができます。その中でオプションの値を設定することもできますが、本稿では new の引数で指定することにします。

最初に、ほとんどのウィジェットで共通するオプションを説明します。

表 : ほとんどのウィジェットで共通のオプション
foreground (fg) 文字や線を描くのに使用する色を指定
background (bg) 背景色の指定
text ウィジェット内に表示されるテキスト
textvariable テキストを格納するオブジェクトを指定
image ウィジェット内に表示されるイメージ
bitmap ウィジェット内に表示されるビットマップ
borderwidth (bd) ウィジェットの枠の幅
relief ウィジェットの枠のスタイル
height ウィジェットの高さ
width ウィジェットの幅
anchor ウィジェットや表示されるデータの位置を指定

ウィジェットの幅と高さは、テキストを表示するウィジェットでは文字数、それ以外のウィジェットはピクセル単位となります。Ruby/Tk の場合、オプションは文字列またはシンボルで指定します。

●オプションの指定と参照

オプションはウィジェットを生成するときに指定しますが、あとからオプションの値を変更することもできます。これにはメソッド configure() を使います。また、オプションの値を参照するにはメソッド cget() を使います。Rub/Tk の場合、オプション名と同じメソッドが定義されていて、このメソッドを使ってアクセスすることもできます。

参考 URL 2-a によると、オプションの値を更新するには以下の方法があるそうです。

  1. widget.configure(option: value, ...)
  2. widget.configure(option, value)
  3. widget.option(value)
  4. widget.option = value
  5. widget[option] = value

1, 2, 3 の返り値は widget で、4, 5 の返り値は value になります。

参考 URL 2-a によると、オプションの値を参照するには以下の方法があるそうです。

  1. widget.cget(option)
  2. widget.option
  3. widget[option]

configure() と cget() は全てのウィジェットで共通に使用することができます。Ruby/Tk では、このようなウィジェットを操作するメソッドが多数用意されています。ちなみに、Tcl/Tk ではウィジェットを操作するメソッドのことを、「ウィジェットコマンド」と呼びます。

●ボタンとラベル

最初は簡単に扱えるボタン (Button) とラベル (Label) から始めましょう。ラベルはウィンドウに文字列を表示するウィジェットです。まず、テキストを表示するウィジェットでよく使用されるオプションを示します。

表 : テキスト表示のオプション
font使用するフォント
underline下線つき表示する文字位置
padx水平方向の詰めもの
pady垂直方向の詰めもの

ボタンにはもうひとつ重要なオプションがあります。

command    押したときに実行する関数を指定

Ruby/Tk の場合、実行する関数を手続きオブジェクトで包んで指定することに注意してください。この手続きオブジェクトがコールバック関数になります。たとえば、command に proc { exit } を指定した場合、そのボタンを押すとアプリケーションが終了することになります。次の例を見てください。

button = TkButton.new(text: "Hello, Ruby/Tk", command: proc { exit })

このように、コールバック関数は proc { } を使って指定してください。

●ジオメトリマネージャ

ボタンを作ったら、それをウィンドウに配置しないといけません。Tk ではジオメトリマネージャ (Geometry Manager) がウィジェットの配置を担当し、3 種類のマネージャが用意されています。

いちばんよく使われるマネージャが Packer です。Placer はウィジェットの位置を座標で指定するため、並べて表示する場合には設定が少々面倒です。たいていの場合は Packer で用が足りるので、Placer を使う機会はあまりないでしょう。電卓やマインスイーパーのように、ボタンを格子状に配置する場合は Gridder が便利です。

●ラベルの作成

それでは簡単な例題として、押したボタンの番号をラベルに表示するプログラムを作ります。最初にラベルを定義します。

リスト : ラベルの定義

# coding: utf-8
require 'tk'

# ラベルの生成
$buff = TkVariable.new('')
label = TkLabel.new(textvariable: $buff)
label.pack

Ruby/Tk の場合、オプション textvariable にはクラス TkVariable のオブジェクトを指定します。データが文字列の場合、メソッド value=() でデータをセットし、メソッド value() でデータを得ることができます。value=() で値を書き換えることで、ラベルの表示を変更することができます。

TkVariable のアクセスメソッドを以下に示します。

●ボタンの作成

次はボタンを作ります。複数のボタンを作る場合、それに対応するコールバック関数を同じ数だけ作るのでは面倒です。そこで、コールバック関数を生成する関数をひとつだけ作成し、それにボタンの番号を渡すことにします。プログラムは次のようになります。

リスト : ボタンの定義

# コールバック関数の生成
def make_cmd(n)
  proc { $buff.value=("button #{n} pressed") }
end

# ボタンの生成
for n in 1..4
  button = TkButton.new(text: "Button #{n}", command: make_cmd(n))
  button.pack
end

Tk.mainloop()

関数 make_cmd() でコールバック関数を生成します。make_cmd() はクロージャを返すことに注意してください。make_cmd() の引数 n にボタン番号を渡すことで、ボタン番号がクロージャに保存されます。したがって、コールバック関数を実行すると、押したボタンの番号を表示することができます。

それでは実行してみてください。

ボタンの画面 Button 1 を押した動作

ボタンが縦に 4 つ表示されましたね。そして、ボタンを押すといちばん上に文字列が表示されます。つまり、ボタンを押すという動作によってプログラムが実行されたわけです。

●Pack マネージャ

次は、pack() について説明しましょう。pack() はウィジェットを上から順に詰め込み、ウィンドウに配置するパッケージマネージャです。例題ではボタンの幅がウィンドウより小さいですが、これをいっぱいに広げるには fill オプションを使います。方向は 'x', 'y' で指定します。両方向に広げるには 'both' を指定します。実際に fill を 追加して確かめてください。

ボタンの画面 fill: 'both' を指定し、button 4 を押した動作

詰め込む方向を変えるにはオプション side を使います。指定できる値は 'top', 'bottom', 'left', 'right' の 4 つです。ウィジェットによって詰め込む方向を変えてもかまいません。ボタンを配置する pack に side: 'left' を追加して実行してみましょう。一番上にラベルが配置され、その下にボタンが 4 つ左から順番に並べられます。

ボタンの画面 side: 'left' を指定し、button 3 を押した動作

このとき、ラベルはウィンドウの中央に表示されます。これを左側に寄せるには anchor オプションを設定します。指定が省略された場合は中央になります。指定方法は次の記号を使います。

 nw --- n --- ne
 |             |
 w      c      e
 |             |
 sw --- s --- se

記号はそれぞれ 'e' (East), 'w' (West), 's' (South), 'n' (North), 'c' (Center) を表します。ラベルを pack するときに、オプション anchor: 'w' を指定すると左寄せに表示します。

ボタンの画面 anchor: 'w' を指定し、button 1 を押した動作

このほかにも、 pack() にはいろいろなオプションが用意されています。


初版 2016 年 8 月 28 日
改訂 2019 年 4 月 14 日
改訂二版 2023 年 2 月 11 日

色とスケール

●色の指定

今回はテキストやボタンに色をつけてみましょう。Tk の場合、色の指定は名前または数値で行います。名前は red, green, blue のように指定します。色の名前は大文字小文字の区別をしません。red と RED は同じ色を表します。数値の場合は、赤、緑、青の三原色を 16 進数で指定します。指定方法には、次の 4 通りの形式があります。

  1. #RGB
  2. #RRGGBB
  3. #RRRGGGBBB
  4. #RRRRGGGGBBBB

色の指定は # から始まり、R, G, B はそれぞれ赤、緑、青の強度を表す数値です。それぞれの色を表す桁数は同じでなければいけません。1. では、R, G, B が 16 段階なので 4096 色の指定ができます。2. は 256 段階なので、約 1600 万色の指定ができます。3. 4. はほとんど使われることはないでしょう。実際の表示は使用しているハードウェアの環境に依存します。

●scale ウィジェット (スライダ)

それでは、R, G, B の値で色がどのように変化するか、サンプルプログラムを作って確かめてみましょう。数値の入力はキーボードから行ってもいいのですが、ここではスケール (scale) というウィジェットを使いましょう。スケールは整数値を表示し、スライダをドラッグするかスケールをクリックすることで、その値を更新することができます。スケールで使用する主なオプションを表に示します。

表 : TkScale の主なオプション
labelスケールのラベル
fromスケールの最小値
toスケールの最大値
orientスケールの方向
showvalue値を表示するか
variableスケールの値を格納するオブジェクトを指定
command値が変化したときに実行するコマンド
resolution解像度

label はスケールの隣に表示する文字列を指定し、form と to で値の範囲を指定します。orient はスケールの方向を指定するもので、orizontal または h を指定すると水平になり、vertical または v で垂直になります。デフォルトでは垂直に設定されます。

showvalue は現在の値を表示するかを設定します。variable はスケールの値を格納する変数を指定しますが、Ruby/Tk の場合はクラス TkVariable のオブジェクトを指定します。

command は、スケールの値が変更されたときに実行する関数を指定します。このとき、スケールの値が引数として関数に渡されます。たとえば、関数 foo() を指定した場合、呼び出されるときは foo(128) となります。このほかにも、ウィジェットの大きさを設定するオプションがあります。

スケールには configure() や cget() のほかに、次に示すメソッドが用意されています。

get() と set() 以外のメソッドは使う機会はあまりないでしょう。

●スケールの使用例

それでは、ボタンの背景色を変化させるプログラムを作ります。

リスト : スケールの使用例

# coding: utf-8
require 'tk'

# スケールの値を格納する
$red = TkVariable.new(0)
$blue = TkVariable.new(0)
$green = TkVariable.new(0)

# ボタン
$button = TkButton.new(text: 'button', bg: '#000')
$button.pack(fill: 'both');

# ボタンの背景色を変更
def change_color(n)
  color = sprintf("#%02x%02x%02x", $red.numeric, $green.numeric, $blue.numeric)
  $button.configure(bg: color)
end

# スケール
s1 = TkScale.new(label: 'red', orient: 'h', from: 0, to: 255,
                 variable: $red, command: proc {|n| change_color(n)})

s2 = TkScale.new(label: 'blue', orient: 'h', from: 0, to: 255,
                 variable: $blue, command: proc {|n| change_color(n)})

s3 = TkScale.new(label: 'green', orient: 'h', from: 0, to: 255,
                 variable: $green, command: proc {|n| change_color(n)})

# ウィジェットの配置
s1.pack(fill: 'both')
s2.pack(fill: 'both')
s3.pack(fill: 'both')

# メインループ
Tk.mainloop()

スケールの値を格納する TkVariable のオブジェクトは、それぞれ $red, $blue, $green というグローバル変数にセットします。値は 0 に初期化しておきます。ボタンのオブジェクトは背景色を変更するときに必要になるので、グローバル変数 $button に格納しておきます。値が変化したときに実行する関数が change_color() です。

関数 sprintf() を使って $red, $green, $blue の値をカラーコードに変換します。数値を 2 桁にそろえるため書式は %02x としています。その後、ボタンの背景色を configure メソッドで変更します。これで、スライダの動きによってボタンの色を変化させることができます。

スライダの画面 スライダで RGB を指定する


初版 2016 年 8 月 28 日
改訂 2019 年 4 月 14 日
改訂二版 2023 年 2 月 11 日

フォントの指定

●フォントの形式

今度は色だけではなくフォントも変更してみましょう。テキストを表示するウィジェットは、オプション font で使用するフォントを指定することができます。フォントの指定にはいくつかの方法があるのですが、次の形式が簡単です。

配列: [family, size, style1, style2]
文字列: 'family size style1 style2'

フォントは配列または文字列を使って指定することができます。文字列で指定する場合は、要素を空白で区切ります。family はフォント名を表します。size はフォントの大きさを表し数値で指定します。style1 と style2 はフォントのスタイルで、次の中から選びます。

style1 : normal, bold, roman, italic
style2 : underline, overstrike

style1 と style2 は省略することができます。

ところで、Ubunts は今まで日本語フォントに Takao フォントが用いられてきましたが、Ubuntu 18.04 からは Noto フォントになりました。Noto フォントは Google によって開発されたオープンソースのフォントです。デフォルトのフォントはコマンド fc-match で求めることができます。

$ fc-match
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
$ fc-match sans
NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
$ fc-match serif
NotoSerifCJK-Regular.ttc: "Noto Serif CJK JP" "Regular"
$ fc-match monospace
NotoSansCJK-Regular.ttc: "Noto Sans Mono CJK JP" "Regular"

sans はゴシック体、serif は明朝体、monospace は等幅フォントを表します。これらの名前はフォント名として使用することができます。その場合はデフォルトの Noto フォントが使用されます。Noto Sans CJK JP がゴシック体、Noto Serif CJK JP が明朝体、Noto Sans Mono CJK JP が等幅フォントになります。

今あなたが使っているパソコンで使用できるフォント名は、メソッド TkFont.fontFamilies で求めることができます。Noto フォントの場合、同じフォント名でも太さ (weight) が異なるフォントが複数用意されています。TkFont.fontFamilies で出力されるのはフォント名だけなので注意してください。たとえば、Noto Sans CJK JP に用意されている太さは次の種類があります。

Thin, Light, DemiLight, Regular, Medium, Bold, Black

太さを変更したい場合はフォント名 Noto Sans CJK JP に太さを連結した名前 (たとえば、Noto Sans CJK JP Light) を family に指定してください。

それでは、実際にフォントを変更してみましょう。次のプログラムを見てください。

リスト : フォントの変更

# coding: utf-8
require 'tk'

str = 'Hello, world, こんにちは世界'
TkLabel.new(text: str, font: ['', 12]).pack
TkLabel.new(text: str, font: ['', 12, 'italic'], fg: 'green').pack
TkLabel.new(text: str, font: ['serif', 14]).pack
TkLabel.new(text: str, font: ['serif', 14, 'italic'], fg: 'blue').pack
TkLabel.new(text: str, font: ['monospace', 16]).pack
TkLabel.new(text: str, font: ['monospace', 16, 'italic'], fg: 'red').pack
TkLabel.new(text: str, font: ['Ricty Diminished', 20, 'underline']).pack
TkLabel.new(text: str, font: ['Ricty Diminished', 20, 'italic', 'underline'], fg: 'brown').pack

Tk.mainloop()

フォントの画面 フォントをいろいろ変えてみる

オプション font にフォントを表す配列を指定するだけです。family に空文字列を指定すると、設定されているフォントは変更されません。フォントを変更せずに size や style1, style2 を変更することができます。Ricty Diminished は M.Hiroi が愛用しているフォントです。Windows と Unix 系 OS の両方で使っています。作者の遊佐泰紀さんに感謝いたします。

Ruby/Tk の場合、フォントの操作にはクラス TkFont を使うこともできます。フォントを変更するときは、new () でオブジェクトを生成して、ウィジェットのオプション font にセットします。次の例を見てください。

リスト : フォントの変更 (2)

# coding: utf-8
require 'tk'

font1 = TkFont.new(['', 12])
font2 = TkFont.new(['serif', 14])
font3 = TkFont.new(['monospace', 16])
font4 = TkFont.new(['Ricty Diminished', 20, 'underline'])
# 
str = 'Hello, world, こんにちは世界'
TkLabel.new(text: str, font: font1).pack
TkLabel.new(text: str, font: font1, fg: 'green').pack
TkLabel.new(text: str, font: font2).pack
TkLabel.new(text: str, font: font2, fg: 'blue').pack
TkLabel.new(text: str, font: font3).pack
TkLabel.new(text: str, font: font3, fg: 'red').pack
TkLabel.new(text: str, font: font4).pack
TkLabel.new(text: str, font: font4, fg: 'brown').pack

Tk.mainloop()

フォントの画面 フォントをいろいろ変えてみる (2)

TkFont.new() でフォントオブジェクトを生成して、それをウィジェットのオプション font にセットするだけです。

●オプションの設定

このように、個々のウィジェットのフォントはオプション font で変更できますが、すべてのラベルウィジェットで使用する共通のフォントを設定したい場合もあるでしょう。Tk は各オプションのデフォルト値を持っています。このため、ユーザーは必要なオプションを指定するだけで、簡単にプログラミングすることができます。このデフォルト値はクラス TkOptionDB のメソッド add() を使って変更することができます。

たとえば、アプリケーションで使用するフォントを変更する場合は、次のように行います。

リスト : デフォルト値の設定

TkOptionDB.add('*font', ['monospace', 14])

これで、テキストを表示するウィジェットは、指定したフォントを使って表示されます。第 1 引数はデフォルト値を設定するウィジェットを表すパターンです。第 2 引数が設定する値です。第 3 引数は省略していますが、優先順位 (priority) を設定することができます。

パターンは、アプリケーション名、ウィジェット名、オプション名をドットで区切って表しますが、ワイルドカード * を指定することもできます。*font の場合は、アプリケーションで使用するフォントを指定することになります。ラベルに対してフォントを設定したい場合は *Label.font となります。Ruby/Tk の場合、クラス名 TkLabel を渡しても動作しないようです。ご注意ください。

たとえば、前回作成したボタンを表示するプログラムに次の 2 行を加えてください。

TkOptionDB.add('*Button.font', ['monospace', 14])
TkOptionDB.add('*Button.background', 'green')

これで、表示されるボタンのフォントと背景色は、設定された値となります。

フォントの画面 ボタンのフォントと背景色を変更


初版 2016 年 8 月 28 日
改訂 2019 年 4 月 14 日
改訂二版 2023 年 2 月 11 日

Copyright (C) 2016-2023 Makoto Hiroi
All rights reserved.

[ PrevPage | Ruby | NextPage ]