34034


GTK+でTextViewのウェジット全体の背景を  
最新のバージョンで変えられるものはありますか？


CC BY-SA 3.0
2017-04-14T08:38:20.180
34008
2017-04-15T08:06:23.373
2017-04-15T08:06:23.373
3054
21169
question
c gtk gui
GTKでTextViewウィジェットの全体の背景を変える


## 概要

Gtk3 ではウィジェットの外観を CSS で設定出来ます。  
これは HTML で行なわれている事と同じ考え方です。  
ただし、CSS などの仕様に厳密に従っているわけではありません。  
リファレンスの関連箇所は [Part IV. Theming in
GTK+](https://developer.gnome.org/gtk3/stable/theming.html) です。

CSSの概要は [Overview of CSS in
GTK+](https://developer.gnome.org/gtk3/stable/chap-css-
overview.html)で、サポートされている CSS プロパティは [Supported CSS
Properties](https://developer.gnome.org/gtk3/stable/chap-css-properties.html)
で説明されています。

## 流れ

まずは変更したいウィジェットの CSS ノードを確認します。  
[GtkTextView](https://developer.gnome.org/gtk3/stable/GtkTextView.html#GtkTextView.description)
は下記のノードを持ちます。

[code]

    CSS nodes
    
    textview.view
    ├── border.top
    ├── border.left
    ├── text
    │   ╰── [selection]
    ├── border.right
    ├── border.bottom
    ╰── [window.popup]
    
[/code]

これを見て、CSS のセレクタを決めます。  
通常のテキスト部分は `textview.view text` で、選択中のテキスト部分は `textview.view text selection`
かな、などとあたりを付けておいて、試行する事になります。

そのセレクタにスタイルを当てるのですが、背景色を変更するならば、前景色（文字などの色）やカーソルの色なども同時に指定する必要があります。  
ユーザーがどのようなテーマを使用しているか分からないからです。  
背景色だけ指定すると、その色がユーザーが使用している前景色と近く、文字などが読めなくなる可能性があります。

[code]

    textview.view text {
        color: white;
        caret-color: green;
        background-color: black;
    }
    textview.view text selection {
        color: red;
        background-color: blue;
    }
    
[/code]

作ったCSS は
[GtkCssProvider](https://developer.gnome.org/gtk3/stable/GtkCssProvider.html)
にロードします。  
その GtkCssProvider を何らかの
[GtkStyleContext](https://developer.gnome.org/gtk3/stable/GtkStyleContext.html)
に追加する事で外観が変わります。  
スタイルをアプリケーション全体に適用するならば、"screen" に対して
[`gtk_style_context_add_provider_for_screen()`](https://developer.gnome.org/gtk3/stable/GtkStyleContext.html#gtk-
style-context-add-provider-for-screen) で追加します。  
特定のウィジェットに適用するならば、そのウィジェットから
[`gtk_widget_get_style_context()`](https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-
widget-get-style-context) で取得した GtkStyleContext に
[`gtk_style_context_add_provider()`](https://developer.gnome.org/gtk3/stable/GtkStyleContext.html#gtk-
style-context-add-provider) で追加します。

## 例

Python になりますがスタイルの設定を数パターン使用している例です。

[code]

    #!/usr/bin/python3
    import gi
    gi.require_version('GLib', '2.0')
    gi.require_version('Gtk', '3.0')
    from gi.repository import GLib
    from gi.repository import Gtk
    
    # イベントループ
    loop = GLib.MainLoop()
    
    # メインウィンドウ
    win = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)
    win.set_title("スタイル変更")
    win.connect("delete-event", lambda *x: loop.quit())
    
    # コンテナ
    box = Gtk.VBox.new(True, 10)
    win.add(box)
    
    # バッファ
    buf = Gtk.TextBuffer.new(None)
    buf.set_text("今日は、世界！\n Hello, world!\n")
    
    # ビュー
    view_01 = Gtk.TextView.new_with_buffer(buf)
    view_01.set_name("top")
    box.add(view_01)
    
    view_02 = Gtk.TextView.new_with_buffer(buf)
    box.add(view_02)
    
    view_03 = Gtk.TextView.new_with_buffer(buf)
    box.add(view_03)
    
    # テキストビューの背景を黒くする CSS
    # top と名付けたテキストビューには個別のスタイルを指定
    # デフォルトのフォントは text ノードではなくテキストビューのトップレベルに指定する模様
    black_css = Gtk.CssProvider.new()
    black_css.load_from_data(
        b"""
    textview.view text {
        color: white;
        caret-color: green;
        background-color: black;
    }
    textview.view text selection {
        color: red;
        background-color: blue;
    }
    
    textview.view#top text {
        color: orange;
    }
    textview.view#top {
        font: 1.5em serif;
    }
        """)
    
    # 上の CSS を全体に設定
    Gtk.StyleContext.add_provider_for_screen(
        win.get_property("screen"),
        black_css,
        Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
    )
    
    # 背景を灰色にする CSS
    gray_css = Gtk.CssProvider.new()
    gray_css.load_from_data(
        b"""
    textview.view text {
        background-color: gray;
    }
        """)
    
    # 上の CSS をテキストビュー 02 に設定
    style_context = view_02.get_style_context();
    style_context.add_provider(gray_css, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
    
    
    # スタート
    win.show_all()
    loop.run()
    
[/code]

![スタイル変更の例](https://i.stack.imgur.com/kK9Ae.png)


CC BY-SA 3.0
2017-04-15T08:04:53.360
34034
2017-04-15T08:04:53.360
3054
34008
answer