What I want to do is make a shortcut keyboard key to switch between Page 1 and Page 2. For instance, pressing Ctrl+S would take me to Page 1 if I am not already there and likewise pressing Ctrl+R would take me to Page 2. I searched the documentation but I couldn't find anything related to what I need. Is there a way to implement it? Please see the below image:
Stack Switcher
Here's the snippet:
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)
Here's a hacky way to get to the first and last children of a stack with two children:
#!/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())
Here's a hacky way to scroll forward and backward through a stack with more than two children:
#!/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())