Search code examples
pythongtkgtk3

Is there a way to sense when the GTK stack changes to a different page


I am writing a program using Gtk3 and Python and I need to detect when the user switches stack pages using a Gtk.StackSidebar. I have searched for a way to do this but couldn't find any information. Is there a way to achieve this functionality or is it not a supported feature in Gtk3? I believe there should be a way to do this, but perhaps I haven't searched thoroughly enough.


Solution

  • I'm assuming that you want to track stack page changes, and not if the stack page changed specifically using the sidebar. This is achievable with the help of notify signal to track currently visible child in the stack using its visible-child property. You can get the stack associated with a sidebar with sidebar.get_stack() if needed.

    A minimal working example:

    #!/usr/bin/env python3
    
    # main.py
    #
    # Run: python3 ./main.py
    #
    # Author: Mohammed Sadiq <www.sadiqpk.org>
    #
    # SPDX-License-Identifier: LGPL-2.1-or-later OR CC0-1.0
    
    import sys
    
    import gi
    
    gi.require_version("Gtk", "3.0")
    from gi.repository import GLib, Gtk
    
    
    class MyApplication(Gtk.Application):
        def __init__(self):
            super().__init__(application_id="org.example.SomeStack")
            GLib.set_application_name("Example Stack")
    
        def _stack_visible_child_changed(self, stack, pspec):
            name = stack.get_visible_child_name()
            print(f"stack child: {name}")
    
        def do_activate(self):
            stack = Gtk.Stack()
            side_bar = Gtk.StackSidebar(stack=stack)
            box = Gtk.Box()
            box.add(side_bar)
            box.add(stack)
    
            stack.connect("notify::visible-child", self._stack_visible_child_changed)
    
            for i in range(0, 6):
                widget = Gtk.Label(label=f"Hello {i}")
                stack.add_titled(widget, f"widget{i}", f"Hello{i}")
    
            window = Gtk.ApplicationWindow(application=self, default_width = 300, default_height=400)
            window.add(box)
            window.show_all()
            window.present()
    
    
    app = MyApplication()
    exit_status = app.run(sys.argv)
    sys.exit(exit_status)