tob*_*n9e 3 gtk glade pygobject gnome-3
我试图做一个适当的例子Gtk.HeaderBar有Gtk.PopoverMenus,显示了不同的部件是如何使用的。我查看了很多示例和代码,但无法弄清楚,如何在Gtk.ModelButton.
特别是这句话对我来说毫无意义:
当通过“action-name”和“action-target”属性指定动作时,按钮的作用(即是普通按钮、复选按钮还是单选按钮)由动作的类型决定,而不是必须使用“角色”属性明确指定。
无论如何,这是我在 PopoverMenu 中仅使用普通小部件的尝试,导致突出显示不一致(应突出显示整行):

所以我的问题是:如何ModelButtons子类化,所以它们显示为适当的小PopoverMenu部件?
这是Python代码:
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()
Run Code Online (Sandbox Code Playgroud)
这是 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>
Run Code Online (Sandbox Code Playgroud)
我设法解决了我的大部分问题。最重要的是,似乎必须使用Gtk.Application和Gtk.ApplicationWindow。我不能说我完全理解为什么,但这使得Actions以 的形式添加Gio.SimpleActions到应用程序中成为可能。Gtk.Builder解析XML菜单的 ,可以简单地使用set_popover- 方法将其添加到菜单中。然后对于 XML 中定义的每个操作(不要忘记app.XML 中Gio.SimpleAction的app.-prefix),在 Python 代码中创建一个(没有-prefix 作为名称)并将其添加到应用程序中。我有一个普通按钮和一个可以工作的检查按钮。仍在努力使用单选按钮,但这可能是另一个问题。
这是Python代码:
from gi.repository import Gio, Gtk, GLib
import sys
class MainApplication(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self,
application_id="needs.dot",
flags=Gio.ApplicationFlags.FLAGS_NONE)
#https://developer.gnome.org/gio/unstable/GApplication.html#g-application-id-is-valid
self.connect("activate", self.activate_window)
def activate_window(self, app):
"""
The activate signal of Gtk.Application passes the MainApplication class
to the window. The window is then set as a window of that class.
"""
self.window = Gtk.ApplicationWindow()
self.window.set_default_size(500, 400)
self.hb = Gtk.HeaderBar()
self.hb.set_show_close_button(True)
self.hb.props.title = "HeaderBar & PopOverMenu"
self.window.set_titlebar(self.hb)
button_settings = Gtk.MenuButton()
icon = Gio.ThemedIcon(name="format-justify-fill-symbolic")
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
button_settings.add(image)
self.hb.pack_end(button_settings)
self.builder = Gtk.Builder()
self.builder.add_from_file("popovermenu_layout.xml")
pom_options = self.builder.get_object("pom_options")
button_settings.set_popover(pom_options)
#self.builder.connect_signals(self) #Not needed because of using actions?
app.add_window(self.window)
#Connects to the action. The first part of the XML name is left away:
#<property name="action-name">app.print</property>
#becomes simply "print".
action_print = Gio.SimpleAction.new("print", None)
action_print.connect("activate", self.print_something)
app.add_action(action_print)
#app.toggle becomes -> toggle
action_toggle = Gio.SimpleAction.new_stateful("toggle", None, GLib.Variant.new_boolean(False))
action_toggle.connect("change-state", self.toggle_toggled)
app.add_action(action_toggle)
btn = Gtk.Button("Button")
self.window.add(btn)
self.window.show_all()
def print_something(self, action, variable):
print("something")
def toggle_toggled(self, action, state):
action.set_state(state)
Gtk.Settings.get_default().set_property("gtk-application-prefer-dark-theme", state)
def on_action_quit_activated(self, action):
self.app.quit()
if __name__ == "__main__":
"""
Creates an instance of the MainApplication class that inherits from
Gtk.Application.
"""
app = MainApplication()
app.run(sys.argv)
Run Code Online (Sandbox Code Playgroud)
和菜单的 XML 文件:
<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="action-name">app.print</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">Print</property>
</object>
</child>
<child>
<object class="GtkModelButton" id="mp_toggle">
<property name="visible">True</property>
<property name="action-name">app.toggle</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="label" translatable="yes">Night Mode</property>
</object>
</child>
</object>
</child>
</object>
</interface>
Run Code Online (Sandbox Code Playgroud)