The Python GTK+ 3 Tutorial【6. Layout Containers】の後半部分を翻訳することで勉強しようと思いますが… だんだん飽きて来ましたー!
そもそもどうしてGUIフレームワークを勉強しようと思ったかというと、自分にとって使いやすい文字起こしツールを作りたいためなのです。アプリ開発の仕事に就きたいとかではないのですね。(シルバーおばさんに雇い主があらわれるとも思わない。)
で、自分用アプリが最終どういう形になるかがまだ見えないので、「どうしてもこれをマスターするんだ!」という気持ちがだんだん弱くなっていく。チュートリアルを丹念に追う根気が薄れていく。ああ、いけませんねえ、「ちょこっといじってすぐ飽きる」いつもの悪い癖が出つつあります。
とはいえ、せっかく始めたので Gtk はマスターしたいです。頑張ります。
6.4. スタックと StackSwitcher
Gtk.Stack は一度に一つの子だけを表示するコンテナです。Gtk.Notebook とは対照的に、Gtk.Stack は表示されている子をユーザが変更する手段を提供しません。代わりに、Gtk.StackSwitcher ウィジェットを一緒に使うことで、この機能を提供することができます。
ページ間の遷移は、スライドやフェードとしてアニメーションさせることができます。これは Gtk.Stack.set_transition_type() で制御できます。これらのアニメーションは “gtk-enable-animations” の設定に従います。
トランジションの速度は Gtk.Stack.set_transition_duration() で調整できます。
Gtk.StackSwitcher ウィジェットは Gtk.Stack のコントローラとして動作します。Gtk.StackSwitcher には、関連するウィジェットのスタック内の様々なページを切り替えるボタンが並んで表示されます。
ボタンの内容はすべて Gtk.Stack の子プロパティから来ています。
複数の Gtk.StackSwitcher ウィジェットを同じ Gtk.Stack ウィジェットに関連付けることができます。
6.4.1. 例
# tut06-04.py
# スタックとStackSwitcherの例
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class StackWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Stack Demo")
self.set_border_width(10)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
self.add(vbox)
stack = Gtk.Stack()
stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
stack.set_transition_duration(1000)
checkbutton = Gtk.CheckButton("Click me!")
stack.add_titled(checkbutton, "check", "Check Button")
label = Gtk.Label()
label.set_markup("<big>A fancy label</big>")
stack.add_titled(label, "label", "A label")
stack_switcher = Gtk.StackSwitcher()
stack_switcher.set_stack(stack)
vbox.pack_start(stack_switcher, True, True, 0)
vbox.pack_start(stack, True, True, 0)
win = StackWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
6.5.ヘッダーバー
Gtk.HeaderBar は横長の Gtk.Box に似ていて、子を先頭や末尾に配置することができます。さらに、タイトルも表示できます。タイトルは、たとえ両側の子が異なるスペースを占めている場合でも、ボックスの幅を基準にして中央に配置されます。
GTK+ がクライアント側でのデコレーションをサポートするようになったので、タイトルバーの代わりに Gtk.HeaderBar を使用することができます (ウィンドウマネージャによってレンダリングされます)。
Gtk.HeaderBar は通常ウィンドウの上部に配置され、下のコンテンツに影響を与えるようなコントロールが格納されます。また、「ウィンドウを閉じるボタン」や「ウィンドウメニュー」などのウィンドウコントロールへのアクセスを提供します。
6.5.1. 例
# tut06-05.py
# HeaderBarの例
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gio
class HeaderBarWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="HeaderBar Demo")
self.set_border_width(10)
self.set_default_size(400, 200)
hb = Gtk.HeaderBar()
hb.set_show_close_button(True)
hb.props.title = "HeaderBar example"
self.set_titlebar(hb)
button = Gtk.Button()
icon = Gio.ThemedIcon(name="mail-send-receive-symbolic")
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
button.add(image)
hb.pack_end(button)
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
Gtk.StyleContext.add_class(box.get_style_context(), "linked")
button = Gtk.Button()
button.add(Gtk.Arrow(Gtk.ArrowType.LEFT, Gtk.ShadowType.NONE))
box.add(button)
button = Gtk.Button()
button.add(Gtk.Arrow(Gtk.ArrowType.RIGHT, Gtk.ShadowType.NONE))
box.add(button)
hb.pack_start(box)
self.add(Gtk.TextView())
win = HeaderBarWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
6.6. フローボックス
この例では、GTK+ 3.12以上が必要です。
※ Gtkのバージョンを確認するには:Gtkをインポートしたあと、Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION, Gtk.MICRO_VERSIONを表示する
Gtk.FlowBox は、子ウィジェットをその向きに応じて順番に配置するコンテナです。
例えば、水平方向の場合、ウィジェットは左から右へと配置され、必要に応じて前の行の下に新しい行が始まります。この場合、幅を狭くすると行数が多くなるので、高さを大きくする必要があります。
同様に垂直方向にすると、ウィジェットは上から下へと配置され、必要に応じて既存の列の右に新しい列を開始します。高さを下げると、より多くの列が必要になるので、幅を大きくする必要があります。
Gtk.FlowBox の子は動的にソートやフィルタリングを行うことができます。
Gtk.FlowBox は Gtk.FlowBoxChild という子だけしか持てませんが、Gtk.Container.add() を通して任意の種類のウィジェットを追加することができ、ボックスとウィジェットの間に Gtk.FlowBoxChild ウィジェットが自動的に挿入されます。
6.6.1. 例
# tut06-06.py
# FlowBoxの例
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk
class FlowBoxWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="FlowBox Demo")
self.set_border_width(10)
self.set_default_size(400, 230)
header = Gtk.HeaderBar(title="Flow Box")
header.set_subtitle("Sample FlowBox app")
header.props.show_close_button = True
self.set_titlebar(header)
scrolled = Gtk.ScrolledWindow()
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
flowbox = Gtk.FlowBox()
flowbox.set_valign(Gtk.Align.START)
flowbox.set_max_children_per_line(30)
flowbox.set_selection_mode(Gtk.SelectionMode.NONE)
self.create_flowbox(flowbox)
scrolled.add(flowbox)
self.add(scrolled)
self.show_all()
def on_draw(self, widget, cr, data):
context = widget.get_style_context()
width = widget.get_allocated_width()
height = widget.get_allocated_height()
Gtk.render_background(context, cr, 0, 0, width, height)
r, g, b, a = data["color"]
cr.set_source_rgba(r, g, b, a)
cr.rectangle(0, 0, width, height)
cr.fill()
def color_swatch_new(self, str_color):
color = Gdk.color_parse(str_color)
rgba = Gdk.RGBA.from_color(color)
button = Gtk.Button()
area = Gtk.DrawingArea()
area.set_size_request(24, 24)
area.connect("draw", self.on_draw, {"color": rgba})
button.add(area)
return button
def create_flowbox(self, flowbox):
colors = [
"AliceBlue",
"AntiqueWhite",
"AntiqueWhite1",
"AntiqueWhite2",
"AntiqueWhite3",
"AntiqueWhite4",
"aqua",
"aquamarine",
"aquamarine1",
"aquamarine2",
"aquamarine3",
"aquamarine4",
"azure",
"azure1",
"azure2",
"azure3",
"azure4",
"beige",
"bisque",
"bisque1",
"bisque2",
"bisque3",
"bisque4",
"black",
"BlanchedAlmond",
"blue",
"blue1",
"blue2",
"blue3",
"blue4",
"BlueViolet",
"brown",
"brown1",
"brown2",
"brown3",
]
for color in colors:
button = self.color_swatch_new(color)
flowbox.add(button)
win = FlowBoxWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
6.7.ノートブック
Gtk.Notebook ウィジェットは、片側のエッジに沿ったタブを使ってページを切り替えられるような Gtk.Container です。
GtkNotebookには多くの設定オプションがあります。中でも、タブをどの辺に表示するか (Gtk.Notebook.set_tab_pos() を参照)、タブが多すぎてノートに収まらない場合はノートブックを大きくするか矢印を追加したりするかどうか (Gtk.Notebook.set_scrollable() を参照) 、ユーザがページを切り替えるためのポップアップメニューがあるかどうか(Gtk.Notebook.popup_enable(), Gtk.Notebook.popup_disable() を参照)が指定できます。
6.7.1. 例
# tut06-07.py
# Notebookの例
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Simple Notebook Example")
self.set_border_width(3)
self.notebook = Gtk.Notebook()
self.add(self.notebook)
self.page1 = Gtk.Box()
self.page1.set_border_width(10)
self.page1.add(Gtk.Label("デフォルトページです!"))
self.notebook.append_page(self.page1, Gtk.Label("Plain Title"))
self.page2 = Gtk.Box()
self.page2.set_border_width(10)
self.page2.add(Gtk.Label("タイトル画像付きのページです。"))
self.notebook.append_page(
self.page2, Gtk.Image.new_from_icon_name("help-about", Gtk.IconSize.MENU)
)
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()