L'Isola di Niente
L'Isola di Niente » PyGObject Tips » テーマ、スタイル、CSS

テーマ、スタイル、CSS

GTK3 は見た目を変更する手段を色々と用意しています。
ただし以下の処理は現時点では GNOME3 環境以外では無視される。

ダークテーマ

Totem, Eye of GNOME に適用されているような暗目な外観。
映像や画像が観やすくなるそうです。
#!/usr/bin/env python3

from gi.repository import Gtk

settings = Gtk.Settings.get_default()
# Set Dark Theme
settings.props.gtk_application_prefer_dark_theme = True
# or
#settings.set_property('gtk-application-prefer-dark-theme', True)

w = Gtk.Window()
w.connect("delete-event", Gtk.main_quit)
w.show()
Gtk.main()

img/dark_theme.png

ツールバースタイル

GNOME3 アプリのメインツールバーに適用されているグラデーション。
メインであることが解りやすい以外のメリットは無いけど GTK3 製だとアピールにはなる。
#!/usr/bin/env python3

from gi.repository import Gtk, Gdk

ui_str = """<ui>
    <toolbar name="ToolBar">
        <toolitem action="open"/>
        <toolitem action="save"/>
        <separator/>
        <toolitem action="quit"/>
    </toolbar>
</ui>"""

class Win(Gtk.Window):
    """
        GtkUIManager でメニュー、ツールバー、右クリックメニュー
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        # GtkUIManager いつもの処理
        uimanager = Gtk.UIManager()
        accelgroup = uimanager.get_accel_group()
        self.add_accel_group(accelgroup)
        actiongroup = Gtk.ActionGroup("gnome_3_toolbar")
        action_entry = [
            ("open", Gtk.STOCK_OPEN, None, None, "おーぷん", self.on_menu),
            ("save", Gtk.STOCK_SAVE, None, None, "おーぷん", self.on_menu),
            ("quit", Gtk.STOCK_QUIT, None, None, "しゅーりょー", Gtk.main_quit) ]
        actiongroup.add_actions(action_entry)
        uimanager.insert_action_group(actiongroup, 0)
        uimanager.add_ui_from_string(ui_str)
        # ツールバーを取り出す
        toolbar = uimanager.get_widget("/ToolBar")
        # ツールバーにスタイル割付
        style = toolbar.get_style_context()
        style.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
        # パッキング
        drawingarea = Gtk.DrawingArea()
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        vbox.pack_start(toolbar, False, True, 0)
        vbox.pack_start(drawingarea, True, True, 0)
        self.add(vbox)
        # いつもの処理
        self.set_title("GNOME3 Toolbar")
        self.connect("delete-event", Gtk.main_quit)
        self.resize(200, 100)
        self.show_all()

    def on_menu(self, action, data=None):
        pass

if __name__ == "__main__":
    Win()
    Gtk.main()

img/toolbar.png

CSS

GtkCssProvider
を利用して HTML の CSS のような手段でスタイルを定義することもできます。

GdkScreen を得て GtkCssProvider を作成し CSS を読み込む。
load_from_path で別体にした CSS ファイルを割り当てるほうが一般的かと。
それらを GtkStyleContext に割り当てる、下記サンプルのようにするだけ。
#!/usr/bin/env python3

from gi.repository import Gtk

css_str = '''

/* 普通に指定 */
GtkEntry {
    color: blue;
}

/* .entry でも意味は同じ、インスタンス名ではない */
.entry:selected {
    background-color: red;
}

/* 自作クラスは __gtype_name__ で指定 */
MyLabelName {
    color: red;
}

/* ワイルドカードも使える */
*:hover {
    color: green;
}
*:active {
    background-color: yellow;
}'''



class MyLabel(Gtk.Label):
    __gtype_name__ = 'MyLabelName'
    def __init__(self, text):
        Gtk.Label.__init__(self, text)

class CssWin(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_title("CSS Test")
        self.connect("delete-event", Gtk.main_quit)
        vbox = Gtk.Box.new(Gtk.Orientation.VERTICAL, 0)
        self.add(vbox)
        # GtkCssProvider
        provider = Gtk.CssProvider()
        #provider.load_from_path('style.css')
        provider.load_from_data(css_str.encode("utf-8")) #Python3 は UCS-4 なので要変換
        # GtkStyleContext
        Gtk.StyleContext.add_provider_for_screen(
                self.get_screen(),
                provider,
                Gtk.STYLE_PROVIDER_PRIORITY_USER)
        # pack
        label = MyLabel("自作クラスは __gtype_name__ で指定")
        vbox.pack_start(label, False, False, 0)
        entry1 = Gtk.Entry()
        vbox.pack_start(entry1, False, False, 0)
        entry2 = Gtk.Entry()
        vbox.pack_start(entry2, False, False, 0)
        button = Gtk.Button.new_with_label("ボタンを押すと黄色になる")
        vbox.pack_start(button, False, False, 0)
        r1 = Gtk.RadioButton.new_with_label_from_widget(None, "選択したほうが")
        r2 = Gtk.RadioButton.new_with_label_from_widget(r1, "黄色になるよ")
        vbox.pack_start(r1, False, False, 0)
        vbox.pack_start(r2, False, False, 0)
        #
        self.show_all()

w = CssWin()
Gtk.main()

img/css.png

現状グラデーション等がうまくいかないようです。
Copyright(C) sasakima-nao All rights reserved 2002 --- 2017.