代码之家  ›  专栏  ›  技术社区  ›  user8272300

如何在Gtk StackSwitcher中使用键盘快捷键?

  •  0
  • user8272300  · 技术社区  · 8 年前

    我想做的是制作一个快捷键,在第1页和第2页之间切换。例如,按 Ctrl键 + S 如果我还没到第一页,我会把我带到第一页 Ctrl键 + R 会带我到第二页。我搜索了 documentation 但我找不到任何与我需要的相关的东西。有没有办法实现它?请参见下图:

    堆栈切换器

    enter image description here

    以下是片段:

    class App(Gtk.Application):
    def __init__(self, *args, **kwargs):
        super(App, self).__init__(*args, **kwargs)
        self.connect('activate', self.on_activate)
    
        self.send_stack = None
        self.receive_stack = None
        self.send_receive_stack = None
        self.header_button_handler_id = None
        self.pre_sign_widget = None
    
    def on_activate(self, app):
        ui_file_path = os.path.join(
            os.path.dirname(os.path.abspath(__file__)),
            "app.ui")
        appwindow = 'applicationwindow1'
        builder = Gtk.Builder()
        builder.add_objects_from_file(ui_file_path, [appwindow])
        window = builder.get_object(appwindow)
        window.set_wmclass ("sign", "sign")
        window.set_title("sign")
        window.connect("delete-event", self.on_delete_window)
        self.headerbar = window.get_titlebar()
        self.header_button = builder.get_object("back_refresh_button")
        self.header_button.connect('clicked', self.on_header_button_clicked)
    
        sw = builder.get_object('stackswitcher1')
        # I want to be able to press Alt+S and Alt+R respectively
        # to switch the stack pages to Send and Receive.
        # sw.get_children()
        self.stack_switcher = sw
    
        self.send_receive_stack = builder.get_object("send_receive_stack")
        self.send_receive_stack.connect('notify::visible-child',
            self.on_sr_stack_switch)
    
        ## Load Send part
        self.send = SendApp()
        ss = self.send.stack
        p = ss.get_parent()
        if p:
            p.remove(ss)
        ss.connect('notify::visible-child', self.on_send_stack_switch)
        ss.connect('map', self.on_send_stack_mapped)
        klw = self.send.klw
        klw.connect("key-activated", self.on_key_activated)
        klw.connect("map", self.on_keylist_mapped)
        klw.props.margin_left = klw.props.margin_right = 15
        self.send_stack = ss
        ## End of loading send part
    
        # Load Receive part
        self.receive = PswMappingReceiveApp(self.on_presign_mapped)
        rs = self.receive.stack
    
        rs.connect('notify::visible-child',
            self.on_receive_stack_switch)
    
    
        scanner = self.receive.scanner
        scanner.connect("map", self.on_scanner_mapped)
        self.receive_stack = rs
    
        self.send_receive_stack.add_titled(self.send_stack,
            "send_stack", _("Send"))
        self.send_receive_stack.add_titled(rs,
            "receive_stack", _("Receive"))
    
        accel_group = Gtk.AccelGroup()
        window.add_accel_group(accel_group)
        self.receive.accept_button.add_accelerator("clicked", accel_group, ord('o'), Gdk.ModifierType.MOD1_MASK,
                                                   Gtk.AccelFlags.VISIBLE)
        self.receive.accept_button.set_can_default(True)
    
        window.show_all()
        self.add_window(window)
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   theGtknerd    8 年前

    这里有一种简单的方法,可以找到包含两个子元素的堆栈的第一个子元素和最后一个子元素:

    #!/usr/bin/env python
    
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk, GdkPixbuf, Gdk
    import os, sys
    
    class GUI:
        def __init__(self):
    
            self.stack  = Gtk.Stack()
            switcher = Gtk.StackSwitcher()
            switcher.set_stack(self.stack)
            label1 = Gtk.Label("label 1")
            label2 = Gtk.Label("label 2")
            label3 = Gtk.Label("label 3")
            self.stack.add_titled (label1, "1", "Page 1")
            self.stack.add_titled (label2, "2", "Page 2")
            self.stack.add_titled (label3, "3", "Page 3")
            box = Gtk.Box()
            box.pack_start(switcher, True, False, 0)
            box.pack_start(self.stack, True, True, 0)
            box.set_orientation(Gtk.Orientation.VERTICAL)
            window = Gtk.Window()
            window.add(box)
    
            window.show_all()
            window.connect("key-press-event", self.key_press)
    
        def key_press (self, window, event):
            keyname = Gdk.keyval_name(event.keyval)
            if not Gdk.ModifierType.CONTROL_MASK:
                #only continue when the CTRL key is down
                return         
    
            #get the last child
    
            if keyname == "r":
                for child in self.stack.get_children(): 
                    self.stack.set_visible_child(child)
    
            #get the first child
    
            if keyname == "s":
                for child in self.stack.get_children():
                    self.stack.set_visible_child(child)
                    return
    
        def on_window_destroy(self, window):
            Gtk.main_quit()
    
    def main():
        app = GUI()
        Gtk.main()
    
    if __name__ == "__main__":
        sys.exit(main())
    

    以下是一种在包含两个以上子级的堆栈中前后滚动的黑客方法:

    #!/usr/bin/env python
    
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk, GdkPixbuf, Gdk
    import os, sys
    
    class GUI:
        def __init__(self):
    
            self.stack  = Gtk.Stack()
            switcher = Gtk.StackSwitcher()
            switcher.set_stack(self.stack)
            label1 = Gtk.Label("label 1")
            label2 = Gtk.Label("label 2")
            label3 = Gtk.Label("label 3")
            self.stack.add_titled (label1, "1", "Page 1")
            self.stack.add_titled (label2, "2", "Page 2")
            self.stack.add_titled (label3, "3", "Page 3")
            box = Gtk.Box()
            box.pack_start(switcher, True, False, 0)
            box.pack_start(self.stack, True, True, 0)
            box.set_orientation(Gtk.Orientation.VERTICAL)
            window = Gtk.Window()
            window.add(box)
    
            window.show_all()
            window.connect("key-press-event", self.key_press)
    
        def key_press (self, window, event):
            keyname = Gdk.keyval_name(event.keyval)
            if not Gdk.ModifierType.CONTROL_MASK:
                #only continue when the CTRL key is down
                return         
    
            #forward scroll
    
            #variable to capture the active widget
            previous_child_active = False  
            if keyname == "r":
                #iterate over the stack children
                for child in self.stack.get_children(): 
                    if previous_child_active == True: 
                        # the last widget was the one that was active
                        self.stack.set_visible_child(child)
                        #finished
                        return                          
                    #remember if the previous child was active
                    previous_child_active = self.stack.get_visible_child() == child
    
            #reverse scroll
    
            #variable to capture the last widget we iterated
            previous_child = None        
            if keyname == "s":
                #iterate over the stack children
                for child in self.stack.get_children():
                    if self.stack.get_visible_child() == child and previous_child != None: 
                        #this is the active widget, so we set the previous active
                        self.stack.set_visible_child(previous_child)
                        #finished
                        return                    
                    #remember the last widget       
                    previous_child = child       
    
        def on_window_destroy(self, window):
            Gtk.main_quit()
    
    def main():
        app = GUI()
        Gtk.main()
    
    if __name__ == "__main__":
        sys.exit(main())