Paepoi » PyGObject Tips » Gtk(PyGObject) Tips | CSS
Gtk(PyGObject) Tips | CSS
# 最終更新日 2019.08.25
2019 年現在の仕様に追記と書き換え。
GtkCssProvider というものを使います。
基本的には Widget の name プロパティを設定、CSS に # の接頭子で指定できます。
複数の Widget に同じ name プロパティを指定しても問題ありません。
アプリ全体(GdkScreen 全体)に一括登録するには以下のようにします。
動かすと上記と同様に表示されることが確認できます。
ただし GTK+ ではタイトルバーを含め文字列表示は全部 GtkLabel みたいな感じです。
ボタンも全部 GtkButton 派生です、これらに影響するのでこの方法を使う場合は慎重に。
下記でも動かすと [閉じる] ボタンが赤くなってしまうのが確認できます。
GTK+ CSS Properties: GTK+ 3 Reference Manual
上記公式にサンプルがいくつか載っています、少し解り辛いですが。
スタイルの他にアニメーションやキーバインドの設定までできるようです。
色々試して自力で発掘しましょう、Linux はそんなもんです。
2019 年現在の仕様に追記と書き換え。
GtkCssProvider
GTK+ では Widget で利用するフォントや色等は CSS を使って指定します。GtkCssProvider というものを使います。
基本的には Widget の name プロパティを設定、CSS に # の接頭子で指定できます。
複数の Widget に同じ name プロパティを指定しても問題ありません。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk BUTTON_CSS = ''' /* name property で指定 */ #MyButton { color: red; } #MyButton:active { color: blue; }''' ENTRY_CSS = ''' #MyEntry { font-style: italic; }''' class Win(Gtk.ApplicationWindow): ''' name は重複してもいい ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False) # button = Gtk.Button(label='ボタンを押すと青色になる', name='MyButton') # GtkCssProvider provider = Gtk.CssProvider() # 文字列から CSS を読み込む、Python3 は UCS-4 なので要変換 provider.load_from_data(BUTTON_CSS.encode('utf-8')) #provider.load_from_path('style.css') # ファイルから読み込む場合 # GtkStyleContext context = button.get_style_context() context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # entry = Gtk.Entry(name='MyEntry') entry.props.buffer.props.text = 'SUZUKI' # 同様に provider2 = Gtk.CssProvider() provider2.load_from_data(ENTRY_CSS.encode('utf-8')) context = entry.get_style_context() context.add_provider(provider2, Gtk.STYLE_PROVIDER_PRIORITY_USER) # pack vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(button, False, False, 0) vbox.pack_start(entry, False, False, 0) # self.add(vbox) self.show_all() class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_startup(self): Gtk.Application.do_startup(self) Win(self) def do_activate(self): self.props.active_window.present() app = App() app.run(sys.argv)
CSS の一括指定
上記の手段だと Widget 毎に登録する必要があり複数指定したい場合は面倒です。アプリ全体(GdkScreen 全体)に一括登録するには以下のようにします。
動かすと上記と同様に表示されることが確認できます。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk APP_CSS = ''' /* 一つの CSS で指定 */ #MyButton { color: red; } #MyButton:active { color: blue; } #MyEntry { font-style: italic; }''' class Win(Gtk.ApplicationWindow): ''' name は重複してもいい ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False) # button = Gtk.Button(label='ボタンを押すと青色になる', name='MyButton') # GtkCssProvider provider = Gtk.CssProvider() provider.load_from_data(APP_CSS.encode('utf-8')) # GtkStyleContext context = self.get_style_context() context.add_provider_for_screen( self.get_screen(), provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # entry = Gtk.Entry(name='MyEntry') entry.props.buffer.props.text = 'SUZUKI' # pack vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(button, False, False, 0) vbox.pack_start(entry, False, False, 0) # self.add(vbox) self.show_all() class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_startup(self): Gtk.Application.do_startup(self) Win(self) def do_activate(self): self.props.active_window.present() app = App() app.run(sys.argv)
Widget のデフォルトを変更
CSS 定義に Widget 名から 'Gtk' を外し全部小文字にすれば名前を付ける必要もありません。ただし GTK+ ではタイトルバーを含め文字列表示は全部 GtkLabel みたいな感じです。
ボタンも全部 GtkButton 派生です、これらに影響するのでこの方法を使う場合は慎重に。
下記でも動かすと [閉じる] ボタンが赤くなってしまうのが確認できます。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk APP_CSS = ''' /* Widget すべてで指定 */ button { color: red; } button:active { color: blue; } entry { font-style: italic; }''' class Win(Gtk.ApplicationWindow): ''' 閉じるボタンまで赤くなる... ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False) # button = Gtk.Button(label='ボタンを押すと青色になる') # GtkCssProvider provider = Gtk.CssProvider() provider.load_from_data(APP_CSS.encode('utf-8')) # GtkStyleContext context = self.get_style_context() context.add_provider_for_screen( self.get_screen(), provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # entry = Gtk.Entry() entry.props.buffer.props.text = 'SUZUKI' # pack vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(button, False, False, 0) vbox.pack_start(entry, False, False, 0) # self.add(vbox) self.show_all() class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_startup(self): Gtk.Application.do_startup(self) Win(self) def do_activate(self): self.props.active_window.present() app = App() app.run(sys.argv)
利用できるスタイル
GTK+ CSS Overview: GTK+ 3 Reference ManualGTK+ CSS Properties: GTK+ 3 Reference Manual
上記公式にサンプルがいくつか載っています、少し解り辛いですが。
スタイルの他にアニメーションやキーバインドの設定までできるようです。
色々試して自力で発掘しましょう、Linux はそんなもんです。
#!/usr/bin/env python3 import sys, gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk APP_CSS = ''' /** * グラデーションサンプルのコピペ */ #MyButton { background-image: radial-gradient(ellipse at center, yellow 0%, green 100%); } #MyButton:active { color: blue; } /** * キーバインドサンプルのコピペ * 公式サンプルにはセミコロンが付いているけど非標準エラーになる */ @binding-set binding-set1 { bind "<alt>Left" { "move-cursor" (visual-positions, -3, 0) }; } @binding-set binding-set2 { bind "<alt>Right" { "move-cursor" (visual-positions, 3, 0) }; } #MyEntry { font: 10pt Sans; -gtk-key-bindings: binding-set1, binding-set2; }''' class Win(Gtk.ApplicationWindow): ''' Entry で Alt+矢印キーで 3 つづつカーソルが移動する ''' def __init__(self, app): Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False) # button = Gtk.Button(label='ボタンを押すと青色になる', name='MyButton') # GtkCssProvider provider = Gtk.CssProvider() provider.load_from_data(APP_CSS.encode('utf-8')) # GtkStyleContext context = self.get_style_context() context.add_provider_for_screen( self.get_screen(), provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) # entry = Gtk.Entry(name='MyEntry') entry.props.buffer.props.text = 'SUZUKI' # pack vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) vbox.pack_start(button, False, False, 0) vbox.pack_start(entry, False, False, 0) # self.add(vbox) self.show_all() class App(Gtk.Application): def __init__(self): Gtk.Application.__init__(self) def do_startup(self): Gtk.Application.do_startup(self) Win(self) def do_activate(self): self.props.active_window.present() app = App() app.run(sys.argv)
Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.