Paepoi

Paepoi » PyGObject Tips » Gtk(PyGObject) Tips | マルチライン EDIT

Gtk(PyGObject) Tips | マルチライン EDIT

# 最終更新日 2019.08.25

2019 年現在の仕様に追記と書き換え。

GtkTextView
GtkTextView はいわゆるマルチライン EDIT です。
View という名前ですが文字列の書き込みも行うこともできます。
文字列を流し込んだり取得するには GtkTextBuffer を得てやりとりします。
GtkScrolledWindow を噛まさないと流し込んだ文字列分サイズが大きくなるので注意。
#!/usr/bin/env python3

import sys, gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk#, Pango

TEXTVIEW_CSS = '''
#MyTextView {
    font: 10pt Monospace;
}'''

class Win(Gtk.ApplicationWindow):
    '''
        CSS については別ページにて
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py')
        # GtkTextView
        view = Gtk.TextView(name='MyTextView')
        #
        # Font の指定、以下は非推奨になりました
        #font_desc = Pango.font_description_from_string('Monospace 9')
        #view.override_font(font_desc)
        #
        # GtkCssProvider でフォント指定してください
        provider = Gtk.CssProvider()
        # 文字列から CSS を読み込む、Python3 は UCS-4 なので要変換
        provider.load_from_data(TEXTVIEW_CSS.encode('utf-8'))
        #provider.load_from_path('style.css') # ファイルから読み込む場合
        # GtkStyleContext
        context = view.get_style_context()
        context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
        #
        # このスクリプト自身を読み込む
        with open(__file__) as f:
            s = f.read()
            view.get_buffer().set_text(s)
        # GtkScrolledWindow
        sw = Gtk.ScrolledWindow(child=view)
        self.add(sw)
        self.resize(300, 300)
        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/gtktextview.png
GtkFontButton
GtkFontButton は GtkFontChooserDialog を呼び出すボタンです。
GtkFontButton 自体に GtkFontChooser がインプリメントされています。
フォント名、サイズ、ウエイト、イタリック等は以下のように適用します。
#!/usr/bin/env python3

import sys, gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Pango

TPL = '''
#MyTextView {{
    font: {0}pt "{1}";
    font-weight: {2};
    font-style: {3};
}}'''

class Win(Gtk.ApplicationWindow):
    '''
        Font Set
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py')
        # GtkTextView
        self.view = Gtk.TextView(name='MyTextView')
        # このスクリプト自身を読み込む
        with open(__file__) as f:
            s = f.read()
            self.view.get_buffer().set_text(s)
        # GtkFontButton
        button = Gtk.FontButton()
        button.connect('font-set', self.on_font_set)
        # GtkScrolledWindow
        sw = Gtk.ScrolledWindow(child=self.view)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(button, False, False, 0)
        vbox.pack_start(sw, True, True, 0)
        self.add(vbox)
        self.resize(300, 300)
        self.show_all()

    def on_font_set(self, button):
        '''
            フォントダイアログで選択を完了した場合のハンドラ
        '''
        desc = button.get_font_desc()
        # PangoFontDescription からフォント情報を得る
        size = desc.get_size() // Pango.SCALE
        name = desc.get_family()
        weight = desc.get_weight() // 1 # enum 定義のままなので整数に変換
        if weight == Pango.Weight.NORMAL:
            w = 'normal'
        elif weight == Pango.Weight.BOLD:
            w = 'bold'
        else:
            w = weight
        style = desc.get_style()
        if style == Pango.Style.OBLIQUE:
            s = 'oblique'
        elif style == Pango.Style.ITALIC:
            s = 'italic'
        else:
            s = 'normal'
        # 値をタイトルバーで確認
        self.props.title = f'{size}|{name}|{w}|{s}'
        # CSS に変換
        css = TPL.format(size, name, w, s)
        # GtkCssProvider
        provider = Gtk.CssProvider()
        provider.load_from_data(css.encode('utf-8'))
        self.view.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)

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/gtkfontbutton.png
GtkSourceView
GtkSourceView は Gedit や Anjuta 等のエディタ部分そのものです。
行番号表示機能等は組み込みされていますし色分け表示手段もあらかじめ用意されています。
自身で色分け等の定義を作ることも可能ですが、ここでは Gedit と同じ色分け表示を。
#!/usr/bin/env python3

import sys, gi
gi.require_version('Gtk', '3.0')
gi.require_version('GtkSource', '4')
from gi.repository import Gtk, GtkSource

TEXTVIEW_CSS = '''
#MySourceView {
    font: 10pt Monospace;
}'''

class Win(Gtk.ApplicationWindow):
    '''
        CSS については別ページにて
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py')
        # GtkTextView
        view = GtkSource.View(show_line_numbers=True, name='MySourceView')
        # CSS
        provider = Gtk.CssProvider()
        provider.load_from_data(TEXTVIEW_CSS.encode('utf-8'))
        view.get_style_context().add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
        #
        # Python3 の色分けを割り当て
        #
        lang_man = GtkSource.LanguageManager()
        lang = lang_man.guess_language(None, 'text/x-python3')
        buf = view.get_buffer()
        buf.set_language(lang)
        #
        # このスクリプト自身を読み込む
        with open(__file__) as f:
            s = f.read()
            buf.set_text(s)
        # GtkScrolledWindow
        sw = Gtk.ScrolledWindow(child=view)
        self.add(sw)
        self.resize(300, 300)
        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/gtksourceview.png
Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.