使用PyGObject

时间:2015-06-23 20:16:31

标签: gtk glade pygobject gnome-3

我正在尝试使用Gtk.HeaderBar作为一个正确Gtk.PopoverMenus的示例,该Gtk.ModelButton显示了如何使用不同的小部件。我查看了很多示例和代码,但无法弄清楚如何使用ModelButtons

特别是this sentence对我没有意义:

  

当通过“action-name”和“action-target”属性指定动作时,按钮的角色(即它是普通按钮,支票按钮还是单选按钮)由动作的类型和不必使用“role”属性明确指定。

无论如何,这是我尝试在PopoverMenu中使用普通小部件,导致突出显示不一致(整个行应突出显示):

enter image description here

所以我的问题是: PopoverMenu如何进行子类化,因此它们显示为正确的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() - 小部件?

这是Python代码:

<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>

这是PopoverMenu的模型:

[%~d1]==[W:]

1 个答案:

答案 0 :(得分:3)

我设法解决了我的问题的大部分内容。最重要的是,似乎必须使用Gtk.ApplicationGtk.ApplicationWindow。我不能说我完全理解为什么,但这样就可以将ActionsGio.SimpleActions的形式添加到应用程序中。 Gtk.Builder解析菜单的XML,只需使用set_popover - 方法将其添加到菜单中即可。然后,对于XML中定义的每个操作(不要忘记XML中的app. - 前缀),创建Gio.SimpleAction(不带app. - 前缀作为名称) Python代码并添加到应用程序中。我有一个普通的按钮和一个按钮来工作。仍然在与无线电按钮挣扎,但这可能是另一个问题。

这是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)

和菜单的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>