Переключение страниц PyGObject с помощью кнопок

#python #gtk #gtk3 #pygtk #pygobject

Вопрос:

Я хочу переключать страницы с помощью кнопок в Gtk.Стек. Есть 3 страницы, и в строке заголовка приложения есть одна кнопка «вперед» и одна кнопка «назад». Я хочу, чтобы он переходил на следующую страницу при нажатии кнопки «Вперед» и переходил на предыдущую страницу при нажатии кнопки «назад». Его текущее состояние может переключаться только между страницами 1 и 2.

 import gi, os
gi.require_version("Gtk", "3.0")
gi.require_version("Handy", "1")
from gi.repository import Gtk, Handy

Handy.init()

class MyWindow(Handy.Window):
    def __init__(self):
        super().__init__(title="Hello World")
        self.set_default_size(500, 300)

        # WindowHandle
        self.handle = Handy.WindowHandle()
        self.add(self.handle)

        # Box
        self.winbox = Gtk.Box(spacing=6, orientation=Gtk.Orientation.VERTICAL)
        self.handle.add(self.winbox)

        # Headerbar
        self.hb = Handy.HeaderBar()
        self.hb.set_show_close_button(True)
        self.hb.props.title = "Stack Example"
        self.winbox.pack_start(self.hb, False, True, 0)

        # Stack
        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        self.winbox.pack_start(self.stack, True, True, 0)

        # Labels
        self.label = Gtk.Label(label="Page 1")
        self.stack.add_titled(self.label, "page0", "Label")

        self.label = Gtk.Label(label="Page 2")
        self.stack.add_titled(self.label, "page1", "Label")

        self.label = Gtk.Label(label="Page 3")
        self.stack.add_titled(self.label, "page2", "Label")

        # Headerbar button 1
        self.button = Gtk.Button()
        self.button = Gtk.Button.new_from_icon_name("pan-start-symbolic", Gtk.IconSize.MENU)
        self.hb.pack_start(self.button)
        self.button.connect('clicked', self.on_button1_clicked)

        # Headerbar button 2
        self.button2 = Gtk.Button()
        self.button2 = Gtk.Button.new_from_icon_name("pan-end-symbolic", Gtk.IconSize.MENU)
        self.hb.pack_start(self.button2)
        self.button2.connect("clicked", self.on_button2_clicked)

    def on_button1_clicked(self, widget):
        self.stack.set_visible_child_name("page1")
    def on_button2_clicked(self, widget):
        self.stack.set_visible_child_name("page2")


win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
 

апп

Ответ №1:

Я не знаю, есть ли простой способ сделать видимым следующего ребенка в GtkStack контейнере или если у другого контейнера есть эта функция, кроме GtkAssistant .

Тем не менее, есть несколько способов, которыми вы можете реализовать это самостоятельно. Либо вот так:

 def on_button1_clicked(self, widget):
    pages = self.stack.get_children()
    cur_page = self.stack.get_visible_child()
    i = pages.index(cur_page)
    if i == 0: return
    self.stack.set_visible_child(pages[i-1])

def on_button2_clicked(self, widget):
    pages = self.stack.get_children()
    cur_page = self.stack.get_visible_child()
    i = pages.index(cur_page)
    if i == len(pages) - 1: return
    self.stack.set_visible_child(pages[i 1])
 

где вы получаете дочерние элементы стека GtkContainer.get_children() , найдите индекс текущего видимого дочернего элемента, а затем плюс/минус один, чтобы получить следующую/предыдущую страницу.
Предостережение: я не уверен, get_children() всегда ли возвращает дочерние виджеты в том порядке, в котором они добавлены.

В качестве альтернативы в вашей __init__() функции вы можете создать список для хранения имен ваших страниц/виджетов, например self.page_names = ['page0', 'page1', 'page2'] . И тогда вы сможете сделать:

 def on_button1_clicked(self, widget):
    cur_page_name = self.stack.get_visible_child_name()
    i = self.page_names.index(cur_page_name)
    if i == 0: return
    self.stack.set_visible_child_name(self.page_names[i-1])
 

Или, может быть, вы извлекаете номер страницы из имени ребенка (например 0 , из page0 ) с помощью регулярного выражения и создаете имя следующей страницы. Есть много способов сделать это, я лично сохранил бы переменную всех страниц и использовал бы ее, чтобы определить, какая страница следующая/предыдущая.