I am trying to make an example of a proper Gtk.HeaderBar
with Gtk.PopoverMenus
that shows how the different widgets are used. I looked at a lot of examples and code, but can't figure out, how to work the Gtk.ModelButton
.
Especially this sentence makes no sense to me:
When the action is specified via the “action-name” and “action-target” properties, the role of the button (i.e. whether it is a plain, check or radio button) is determined by the type of the action and doesn't have to be explicitly specified with the “role” property.
In any case, here is my attempt to just use normal widgets in the PopoverMenu, leading to inconsistent highlighting (the whole row should be highlighted):
So my question is: How are ModelButtons
subclassed, so they appear as proper PopoverMenu
-widgets?
Here is the Python code:
from gi.repository import Gtk, Gio
class HeaderBarWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="HeaderBar & PopoverMenu")
self.set_border_width(10)
self.set_default_size(400, 400)
builder = Gtk.Builder()
objects = builder.add_objects_from_file("popovermenu_layout.xml", ("pom_options", ""))
pom_opt = builder.get_object("pom_options")
builder.connect_signals(self)
hb = Gtk.HeaderBar()
hb.set_show_close_button(True)
hb.props.title = "HeaderBar & PopoverMenu"
self.set_titlebar(hb)
def on_click(button, popovermenu):
"""
Toggles the respective popovermenu.
"""
if popovermenu.get_visible():
popovermenu.hide()
else:
popovermenu.show_all()
button_opt = Gtk.Button()
icon = Gio.ThemedIcon(name="format-justify-fill-symbolic")
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
button_opt.add(image)
hb.pack_end(button_opt)
pom_opt.set_relative_to(button_opt)
button_opt.connect("clicked", on_click, pom_opt)
self.add(Gtk.TextView())
def print_something(self, modelbutton, event):
print("you pressed a button")
def night_mode_switcher(self, switch, state):
Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", state)
win = HeaderBarWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
And here is the model for the PopoverMenu:
<interface>
<object class="GtkPopoverMenu" id ="pom_options">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="margin">10</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkModelButton" id="mb_print">
<property name="visible">True</property>
<property name="text" translatable="yes">Print</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="button-press-event" handler="print_something" swapped="no"/>
</object>
</child>
<child>
<object class="GtkCheckButton" id="checkbutton1">
<property name="label" translatable="yes">checkbutton</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
</object>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkSwitch" id="switch1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="state-set" handler="night_mode_switcher" swapped="no"/>
<property name="margin_start">9</property>
<property name="margin_end">9</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="mb_night">
<property name="text" translatable="yes">Night Mode</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_start">9</property>
<property name="margin_end">9</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
I managed to solve most of what my question was. Most importantly it seems that one has to use
Gtk.Application
andGtk.ApplicationWindow
. I can't say that I fully understand why, but that makes it possible to addActions
in the form ofGio.SimpleActions
to the application.Gtk.Builder
parses theXML
of the menu, and one can simply add it tot the menu using theset_popover
-method. Then for each action defined in the XML (don't forget theapp.
-prefix in the XML) aGio.SimpleAction
is created (without theapp.
-prefix as name) in the Python-code and added to the application. I got a normal button, and a checkbutton to work. Still struggling with the radiobutton, but that might be another question.Here is the Python-code:
and the XML-file for the menu: