【问题标题】:How do I use keyboard shortcuts with Gtk StackSwitcher?如何在 Gtk StackSwitcher 中使用键盘快捷键?
【发布时间】:2018-08-18 07:38:41
【问题描述】:

我要做的是制作一个快捷键以在第 1 页和第 2 页之间切换。例如,按 Ctrl+S 会带我到第 1 页如果我不在那里并且同样按 Ctrl+R 将带我到第 2 页。我搜索了 documentation 但我找不到与我的内容相关的任何内容需要。有没有办法实现它?请看下图:

堆栈切换器

这是sn-p:

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)

【问题讨论】:

  • 请发布您的代码,以便我们从那里获取。
  • @theGtknerd 我已经更新了问题。

标签: python user-interface gtk pygtk gtk3


【解决方案1】:

这里有一个 hacky 方法来获取具有两个孩子的堆栈的第一个和最后一个孩子:

#!/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())

这是一种在具有两个以上子项的堆栈中向前和向后滚动的 hacky 方法:

#!/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())

【讨论】:

  • 你是救世主!谢谢@theGtknerd
  • 一点帮助@theGtknerd。你能告诉我如何更改我的代码以达到预期的结果吗?我是一个菜鸟,结果对我来说很困难另外我想问一下是否有必要拥有 2 个以上的堆栈孩子?
  • 请发布您的完整代码、Builder/Glade 文件和所有内容。您只发布了 Python 部分。
  • 不,你只需要两个栈子。我的版本适用于两个以上,如果你需要的话。它可以为只有两个孩子以不同的方式工作,但我怀疑这会更容易。
  • 很遗憾,我不能参加。说声望不够。 :(@theGtknerd
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
相关资源
最近更新 更多