Paepoi

Paepoi » PyGObject Tips » Gtk(PyGObject) Tips | ボタン

Gtk(PyGObject) Tips | ボタン

# 最終更新日 2019.08.18

2019 年現在の仕様に追記と書き換え、PyGtk 関連の削除。

GtkButton
GtkButton は標準的なボタンです。
クリックすると clicked シグナルが発生しますのでハンドラを書いて処理を行います。
GtkLabel と同様に use-markup を有効にすればニーモニックにも対応します。
#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        Alt+A でボタンが押されるのが解る
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        buttons = [
            Gtk.Button(label='普通のボタン'),
            Gtk.Button(label='Alt+_A でクリック', use_underline=True),
            Gtk.Button(label='Alt+_B で何も起こらない'),
            # ストックは廃止予定になっています、まだ動くけど
            #Gtk.Button.new_from_stock(Gtk.STOCK_YES), deprecated
            # アイコンボタンはこう呼び出す
            Gtk.Button.new_from_icon_name('open-menu-symbolic', Gtk.IconSize.MENU),
            # 無効にするには sensitive プロパティ
            Gtk.Button(label='無効にする', sensitive=False)
        ]
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        for button in buttons:
            vbox.pack_start(button, False, False, 0)
            button.connect('clicked', self.on_button_clicked)
        self.add(vbox)
        #self.resize(300, 200)
        self.show_all()

    def on_button_clicked(self, button):
        '''
            ボタンが押されるとそのボタンのラベルをタイトルバーに書き出し
        '''
        self.props.title = button.props.label

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/gtkbutton1.png
GtkToggleButton
GtkToggleButton は GtkButton のサブクラスです。
クリックするともう一度クリックするまで凹んだままになります。
凹んでいるかの on off 状態判別に利用します、シグナルは toggled を使います。
サンプルコードは下記 GtkCheckButton にまとめて書いています。

GtkCheckButton
GtkCheckButton は基本的に GtkToggleButton と変わりません。
GtkToggleButton のサブクラスですが見た目が変わった程度だと思ってください。
#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        凹むかチェックマークが入るかどうかしか違いがない
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        tb = Gtk.ToggleButton(label='トグルボタン(_T)', use_underline=True)
        cb = Gtk.CheckButton(label='チェックボタン(_C)', use_underline=True)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(tb, False, False, 0)
        vbox.pack_start(cb, False, False, 0)
        tb.connect('toggled', self.on_tb_button_toggled)
        cb.connect('toggled', self.on_cb_button_toggled)
        self.add(vbox)
        self.show_all()

    def on_tb_button_toggled(self, button):
        if button.props.active:
            self.props.title = 'toggle'

    def on_cb_button_toggled(self, button):
        if button.props.active:
            self.props.title = 'check'

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/gtkbutton2.png
GtkRadioButton
GtkRadioButton は排他のボタンを複数用意してユーザーに選択させる Widget です。
グループは group プロパティに共通の GtkRadioButton を指定したものになります。
GtkCheckButton のサブクラスなので toggled シグナルも使えます。
#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        排他で一つだけアクティブになるのが解る
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        root = None
        for s in ['スカーウェーブ', 'ジェンマ', 'バーグマン']:
            # GtkRadioButton
            r = Gtk.RadioButton(label=s, group=root)
            if not root:
                root = r
            r.connect('toggled', self.on_radio_toggled)
            vbox.pack_start(r, False, False, 0)
        self.add(vbox)
        self.show_all()

    def on_radio_toggled(self, button):
        if button.props.active:
            self.props.title = button.props.label

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/gtkbutton3.png
GtkSwitch
GtkSwitch は GTK3 から追加された Widget で on off 判定に特化したもの。
bool 値を同期させるのに利用、Widget 間だけでなく gsettings の値も同期できます。
又バインド(同期)は双方向、片方向で選べます。
一応 notify::active でシグナルも使えるようにはしているようです。
下記は片方の Widget を ON/OFF するともう片方も追従するサンプルです。
#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        右二つが連動、一番左でタイトルの変更
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        # GtkSwitch と GtkCheckButton のプロパティをを同期
        switch = Gtk.Switch()
        check = Gtk.CheckButton(label='Check')
        GObject.Binding.bind_property(
            switch, 'active',
            check, 'active',
            GObject.BindingFlags.BIDIRECTIONAL )
        # notify::active を使ってみる
        switch2 = Gtk.Switch()
        switch2.connect('notify::active', self.on_swich_activate)
        #
        hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        hbox.pack_start(switch, False, False, 0)
        hbox.pack_start(check, False, False, 0)
        hbox.pack_start(switch2, False, False, 0)
        self.add(hbox)
        self.show_all()

    def on_swich_activate(self, swich, data):
        self.props.title = 'ON' if swich.props.active else 'OFF'

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/gtkbutton4.png
GtkLinkButton
GtkLinkButton はクリックすると gio open コマンドにて指定 URI を開く Widget です。
label と uri プロパティは別に指定できます。
#!/usr/bin/env python3

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

class Win(Gtk.ApplicationWindow):
    '''
        ローカルファイルなら file:// 接頭子でデフォルトアプリで開く
        gio open コマンドで開けるものなら何でもいい
    '''
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app, title='Py', resizable=False)
        # GtkSwitch と GtkCheckButton のプロパティをを同期
        links = [
            Gtk.LinkButton(label='画像', uri='file:///usr/share/icons/gnome/256x256/status/computer-fail.png'),
            Gtk.LinkButton(label='URL', uri='https://www.suzuki.co.jp/'),
            Gtk.LinkButton(label='パス', uri=f'file://{GLib.get_home_dir()}'),
            Gtk.LinkButton(label='ゴミ箱', uri='trash:///'), # ゴミ箱の Gvfs URI
            Gtk.LinkButton(label='テキスト', uri='file:///etc/hostname') # 拡張子不要
        ]
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        for link in links:
            vbox.pack_start(link, 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/gtkbutton5.png
Copyright(C) sasakima-nao All rights reserved 2002 --- 2020.