2015-06-23 42 views
1

我想用Gtk.PopoverMenus來舉例說明正確的Gtk.HeaderBar,它顯示瞭如何使用不同的小部件。我看了很多例子和代碼,但無法弄清楚,如何工作Gtk.ModelButton使用PyGObject正確地構造和突出顯示GtkPopoverMenu

特別this sentence沒有意義的,我說:

當通過「動作名稱」和「行動目標」的屬性,按鈕的作用(即指定的動作是否是一個普通的,檢查或單選按鈕)由動作類型決定,不必用「角色」屬性明確指定。

在任何情況下,這裏是我的嘗試只是使用普通的部件在PopoverMenu,導致不一致的高亮(整行應當強調):

enter image description here

所以我的問題是:ModelButtons如何被分類,所以它們顯示爲正確的PopoverMenu -widgets?

這裏是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() 

這裏是爲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> 

回答

2

我設法解決大部分的東西我的問題。最重要的是,似乎必須使用Gtk.ApplicationGtk.ApplicationWindow。我不能說我完全理解爲什麼,但是這可以將ActionsGio.SimpleActions的形式添加到應用程序中。 Gtk.Builder解析菜單的XML,並且可以使用set_popover-方法簡單地將它添加到菜單中。然後,對於在XML中定義的每個動作(不要忘記XML中的app. -prefix),將在Python代碼中創建一個Gio.SimpleAction(不含app.-前綴作爲名稱)並添加到應用程序中。我有一個正常的按鈕和一個checkbutton工作。仍然在與單選按鈕拼搏,但這可能是另一個問題。

這裏是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> 
+1

而是「格式對齊 - 充填 - 象徵性的」,或許用「開放式菜單-symbolic「作爲菜單按鈕的圖標? –

+0

謝謝。我只是抓住了第一個看起來正確的:) – tobias47n9e

+0

我剛剛發現「open-menu-symbolic」是比較新的(在GTK + 3.14中出現),所以如果你希望你的軟件能夠正常工作,比如Ubuntu 14.04 LTS,你不能使用它。 :/ –