Python GTK+3 チュートリアル

18. ポップオーバー

翻訳して勉強するGtkチュートリアル第18章 Popovers です。そろそろ、「自分用文字起こしツール」の出来上がりイメージを思い描いてもいい段階かなぁと思います。


Gtk.Popover は追加情報を表示するための別ウィンドウで、ボタンメニューやコンテキストメニューの一部としてよく使われます。ポップオーバーの用途はダイアログウィンドウと似ていますが、中断が少なく、ポップオーバーが指し示しているウィジェットとの関連性があるという利点があります。ポップオーバーは小さな三角形で関連するウィジェットに視覚的に接続されています。

ポップオーバーは Gtk.Popover で作成できます。ポップオーバーを開くには Gtk.Widget.show_all() を使用します。

18.1. カスタム・ポップオーバー

ウィジェットは Gtk.Container.add() を使ってポップオーバーに追加することができます。

18.1.1. 例

動作テスト - カスタム・ポップオーバー
# tut18-01.py
# カスタム・ポップオーバー

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk


class PopoverWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Popover Demo")
        self.set_border_width(10)

        outerbox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL)
        self.add(outerbox)

        button = Gtk.Button.new_with_label("Click Me")
        button.connect("clicked", self.on_click_me_clicked)
        outerbox.pack_start(button, False, True, 0)

        self.popover = Gtk.Popover()
        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vbox.pack_start(Gtk.ModelButton("Item 1"), False, True, 10)
        vbox.pack_start(Gtk.Label("Item 2"), False, True, 10)
        self.popover.add(vbox)
        self.popover.set_position(Gtk.PositionType.BOTTOM)

    def on_click_me_clicked(self, button):
        self.popover.set_relative_to(button)
        self.popover.show_all()
        self.popover.popup()

    def on_open_clicked(self, button):
        print('"Open" button was clicked')


win = PopoverWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

18.2. メニュー・ポップオーバー

ポップオーバーは Gtk.Popover.new_from_model() を使って Gio.MenuModel から作成することができ、作成後に Gtk.Popover.bind_model() を使って変更することができます。

18.2.1. 例

動作テスト - メニュー・ポップオーバー
# tut18-02.py
# メニュー・ポップオーバー

import sys

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gio, Gtk

# This would typically be its own file
MENU_XML = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <menu id="app-menu">
    <section>
        <item>
            <attribute name="label">About</attribute>
            <attribute name="action">app.about</attribute>
        </item>
        <item>
            <attribute name="label">Quit</attribute>
            <attribute name="action">app.quit</attribute>
        </item>
    </section>
  </menu>
</interface>
"""


class AppWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        outerbox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL)
        self.add(outerbox)
        outerbox.show()

        builder = Gtk.Builder.new_from_string(MENU_XML, -1)
        menu = builder.get_object("app-menu")

        button = Gtk.MenuButton.new()
        popover = Gtk.Popover.new_from_model(button, menu)
        button.set_popover(popover)

        outerbox.pack_start(button, False, True, 0)
        button.show()
        self.set_border_width(50)


class Application(Gtk.Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, application_id="org.example.myapp", **kwargs)
        self.window = None

    def do_startup(self):
        Gtk.Application.do_startup(self)

        action = Gio.SimpleAction.new("about", None)
        action.connect("activate", self.on_about)
        self.add_action(action)

        action = Gio.SimpleAction.new("quit", None)
        action.connect("activate", self.on_quit)
        self.add_action(action)

    def do_activate(self):
        # We only allow a single window and raise any existing ones
        if not self.window:
            # Windows are associated with the application
            # when the last one is closed the application shuts down
            self.window = AppWindow(application=self, title="Main Window")

        self.window.present()

    def on_about(self, action, param):
        about_dialog = Gtk.AboutDialog(transient_for=self.window, modal=True)
        about_dialog.present()

    def on_quit(self, action, param):
        self.quit()


if __name__ == "__main__":
    app = Application()
    app.run(sys.argv)

18.3. こちらも参照してください。

GNOME DEVELOPER - User interface elements - Popovers


関連記事