[Python+Gtk4でのCSSの使用]Gtk.ListViewの装飾 Gtk.ListViewの項目をツートンカラーで装飾

Gtk.ListViewの項目の装飾

 Gtk.ListViewのようなリスト表示をするWidgetでは、CSSを使用することでさまざまな種類の枠線の追加や、各項目の色を個別に変更であり、視認線に優れたオリジナルのリストを作成することができます。
 今回は、Gtk.ListViewへ①枠線の追加したり、②項目の色指定として項目をツートンカラーにする、③フォーカスした項目の色を指定する方法について紹介します。

今回紹介する内容:
 ・ Gtk.ListViewに枠線を追加する。
 ・Gtk.ListViewの項目の色を指定する。
 ・Gtk.ListViewでフォーカスした項目の色を指定する。

Gtk.ListViewに枠線を追加

 Gtk.ListViewの外枠は、border-styleで枠線の種類、border-colorで枠の色、border-widthで枠線の太さを指定します。※ border-styleを指定しないと枠線は表示されません。

listview {
    border-color:  black;
    border-style: solid;
    border-width: 1pt;
}
内容
none境界線がない状態。色と幅は無視される
dotted丸いドット線
dashed破れ線
solid単一の実線
double2本の実線
bordar-styleの主な値

Gtk.ListViewの項目の色を指定

 Gtk.ListViewの項目部分の装飾は、listview rowによって指示します。rowに:nth-child()を追加すると複数あるrowのうち、特定のrowに対しての装飾を指定することができます。

 nth-child()では、装飾する行はn(n=0,1,2,3…と値が代入される)を使用して指定します。
 例えば、ツートンカラーにする場合では、偶数行を2n、奇数行を2n+1の色をそれぞれ指定しますし、3色に分ける場合は、3n, 3n+1 , 3n+2の色をそれぞれ指定します。今回のサンプルでは項目をツートンカラーにするので、以下のように指定しています。

listview row:nth-child(2n) {
    color: black;
    background: lightskyblue;
    border-color:  black;
    # 省略
}

listview row:nth-child(2n+1) {
    color: black;
    background: white;
    # 省略
}

Gtk.ListViewでフォーカスした項目の色を指定

 Gtk.ListViewのフォーカスした項目の装飾の指定は、以下のようにlistview row:focusによりおこないます。

listview row:focus {
    background: blue;
}

その他のWidgetの装飾

 Gtk.ListView以外にも以下のWidgetに対して状態別の装飾をおこなう方法を記事にしています。

サンプルプログラム

 以下のプログラムを実行すると、下図のように装飾されたGtk.ListViewが表示されます。

listview {
    border-color:  black;
    border-style: solid;
    border-width: 1pt;
}

listview row:nth-child(2n) {
    color: black;
    background: lightskyblue;
    border-color:  black;
    border-width: 10pt;
    padding-left: 10pt;
    padding-right: 10pt;
    padding-top: 5pt;
    padding-bottom: 5pt;
    border-width: 1pt;
    border-color: brown;
    border-top-style: solid;
    border-bottom-style: solid;
}

listview row:nth-child(2n+1) {
    color: black;
    background: white;
    padding-left: 10pt;
    padding-right: 10pt;
    padding-top: 5pt;
    padding-bottom: 5pt;
    border-width: 1pt;
    border-color: brown;
    border-top-style: solid;
    border-bottom-style: solid;
}

listview row:focus {
    background: blue;
}
import gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk, Gio, GObject, Gdk


APPID = 'com.github.taniyoshima.g4_fblog_about_css_listview'


class Data(GObject.Object):

    def __init__(self, data):
        super().__init__()
        self.data = data


class Gtk4TestTest(Gtk.Window):

    def __init__(self, app):
        Gtk.Window.__init__(
            self, application=app, title='Listview Test',
            default_width=400, default_height=300,
        )

        provider = Gtk.CssProvider()
        try:
            provider.load_from_path('main.css')
        except GLib.Error as e:
            print(f"CSSファイルの読み込み失敗 : {e} ")
            return None
        Gtk.StyleContext.add_provider_for_display(
            Gdk.Display.get_default(), provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)

        model = Gio.ListStore()
        model.append(Data('項目1'))
        model.append(Data('項目2'))
        model.append(Data('項目3'))
        model.append(Data('項目4'))
        model.append(Data('項目5'))
        model.append(Data('項目6'))

        smodel = Gtk.SingleSelection(model=model)

        factory = Gtk.SignalListItemFactory()
        factory.connect("setup", self.on_list_item_setup)
        factory.connect("bind", self.on_list_item_bind)

        smodel.connect("selection-changed", self.on_selected_items_changed)

        listview = Gtk.ListView(
            margin_top=20, margin_bottom=20,
            margin_start=20, margin_end=20,
        )
        listview.set_model(smodel)
        listview.set_factory(factory)

        self.set_child(listview)

    def on_selected_items_changed(self, selection, position, n_items):
        selected_item = selection.get_selected_item()
        if selected_item is not None:
            print(f"アイテムが変更されました。: {selected_item.data}")

    def on_list_item_setup(self, factory, item):
        label = Gtk.Inscription()
        item.set_child(label)

    def on_list_item_bind(self, factory, item):
        item.get_child().set_text(item.get_item().data)


class Gtk4TestApp(Gtk.Application):

    def __init__(self):
        Gtk.Application.__init__(self, application_id=APPID)

    def do_activate(self):
        window = Gtk4TestTest(self)
        window.present()


def main():
    app = Gtk4TestApp()
    app.run()


if __name__ == '__main__':
    main()
タイトルとURLをコピーしました