Popovers — PyGObject

Skip to main content
`Ctrl`+`K`

# Popovers

The `Gtk.Popover` is an special kind of window used for displaying additional information and is often used with button menus and context menus. Popovers are attached to a parent widget and point to it. It’s position can be configured with `Gtk.Popover.props.position`. `Gtk.Popover` shows an arrow to visually connect where it points to, this can be disabled setting `Gtk.Popover.props.has_arrow` to `False`.

A `Gtk.Popover` can be opened using `Gtk.Popover.popup()` and hidden with `Gtk.Widget.hide()`.

GTK also provides `Gtk.MenuButton`, it’s an special button that can show and hide a `Gtk.Popover` attached to it using `Gtk.MenuButton.props.popover`.

## Custom Popover

A child widget can be added to a popover using `Gtk.Popover.set_child()`. The parent of the popover can be set using `Gtk.Widget.set_parent()`.

### Example

     1import gi
     2
     3gi.require_version("Gtk", "4.0")
     4from gi.repository import Gtk
     5
     6
     7class PopoverWindow(Gtk.ApplicationWindow):
     8    def __init__(self, **kargs):
     9        super().__init__(**kargs, title="Popover Demo")
    10
    11        self.set_default_size(300, 200)
    12
    13        box = Gtk.Box(
    14            spacing=6,
    15            orientation=Gtk.Orientation.VERTICAL,
    16            halign=Gtk.Align.CENTER,
    17            valign=Gtk.Align.CENTER,
    18        )
    19        self.set_child(box)
    20
    21        popover = Gtk.Popover(child=Gtk.Label(label="Item"))
    22        button = Gtk.MenuButton(label="Click Me", popover=popover)
    23        box.append(button)
    24
    25        button2 = Gtk.Button(label="Click Me 2")
    26        button2.connect("clicked", self.on_button_clicked)
    27        box.append(button2)
    28
    29        self.popover2 = Gtk.Popover(
    30            child=Gtk.Label(label="Another Popup!"), position=Gtk.PositionType.LEFT
    31        )
    32        self.popover2.set_parent(button2)
    33
    34    def on_button_clicked(self, _button):
    35        self.popover2.popup()
    36
    37
    38def on_activate(app):
    39    win = PopoverWindow(application=app)
    40    win.present()
    41
    42
    43app = Gtk.Application(application_id="com.example.App")
    44app.connect("activate", on_activate)
    45
    46app.run(None)

## Menu Popover

GTK also has `Gtk.PopoverMenu`, it’s a `Gtk.Popover` subclass designed to display a menu model.

A popover can be created from a `Gio.MenuModel` using `Gtk.PopoverMenu.new_from_model()` and can be changed after creation with `Gtk.PopoverMenu.props.menu_model`.

`Gtk.MenuButton` also can construct a `Gtk.PopoverMenu` passing it a `Gio.MenuModel` to `Gtk.MenuButton.props.menu_model`.

See also

In GTK Application we also showed examples of menu models.

### Example

    import gi

    gi.require_version("Gtk", "4.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, **kwargs):
            super().__init__(**kwargs)

            self.set_default_size(300, 200)

            headerbar = Gtk.HeaderBar()
            self.set_titlebar(headerbar)

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

            button = Gtk.MenuButton(menu_model=menu_model)
            headerbar.pack_end(button)

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

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

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

            action = Gio.SimpleAction(name="quit")
            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()

    app = Application()
    app.run(None)