Как динамически изменять размеры страниц ноутбука GTK

У меня есть приложение Python, которое использует виджет Gtk.Notebook для отображения разных страниц. Каждая из этих страниц содержит другой набор виджетов, и я заметил, что «самый высокий» виджет в терминах вертикального пространства определяет общий вертикальный размер ноутбука.

Но мне действительно понравилось мое приложение, чтобы изменить размер страниц, чтобы не тратить вертикальное пространство, и адаптироваться, то есть изменять размер до того же вертикального размера, что и виджет, который они содержат. Этот размер изменяется, когда я выбираю каждую страницу.

Test app showing undesired vertical space [/g1]

Вот пример кода для создания этого ноутбука (пример содержит виджет на страницу для простоты)

Короче говоря, как я могу динамически изменять размер страниц ноутбуков при их выборе, чтобы их вертикальное пространство было таким же, как и их дочерний виджет?

5
задан 30 May 2012 в 23:33

8 ответов

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

1
ответ дан 25 July 2018 в 18:42

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 31 July 2018 в 12:35

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 2 August 2018 в 00:51

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 4 August 2018 в 16:22

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 6 August 2018 в 01:01

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 7 August 2018 в 18:28

ЕСЛИ фактический виджет для ноутбука не нужен, но это всего лишь способ совместного использования подобного контента и обеспечения возможности переключения между ними, тогда могут быть лучшие / более простые решения. Вот то, что было в конце, использованном для Qreator :

, основная идея - использовать контейнер, подобный Gtk.Box (называемый page_box в примере ниже) и сохранить только один элемент. Вам также нужен список с содержимым каждой страницы, каждый из которых упакован в один виджет (например, Gtk.Grid ).

for page in page_list:
    self.ui.page_box.add(page.grid)

Здесь page_list является простым список объектов страницы, где объект страницы имеет свойство grid (Gtk.Grid содержит все содержимое страницы).

Наконец, вам необходимо предоставить способ переключения между содержимым, например. с набором кнопок, каждый из которых вызывает метод переключения с соответствующим page_id при нажатии:

def switch_view(self, page_id):
    # hide all pages
    for child in self.ui.page_box.get_children():
        child.hide()
    # show the single page that is active
    self.ui.page_box.get_children()[page_id].show()

Это не буквальный ответ на вопрос, но он может решить ту же проблему.

3
ответ дан 15 August 2018 в 19:08
  • 1
    Это именно то, что мне нужно, спасибо! Я тестировал его для работы над rev 2 примера. Однако при тестировании с помощью реального кода он, похоже, не работал. Я отслеживал это потому, что виджеты в реальном приложении не помещаются непосредственно на страницу ноутбука, а скорее содержатся в сетке на каждой странице. Rev 3 примера иллюстрирует эту ситуацию. – David Planella 31 May 2012 в 15:37
  • 2
    Я соглашусь с ответом, так как это приемлемый способ решения вопроса. Тем не менее, я все еще придерживаюсь своего кода сеткой. Я не уверен в открытии нового вопроса, так как он будет слишком локализован, но в любом случае любые идеи, почему последний примерный код с сеткой не делает размер? Спасибо! – David Planella 31 May 2012 в 15:38
  • 3
    – xubuntix 31 May 2012 в 16:05
  • 4
    – xubuntix 31 May 2012 в 16:26
  • 5
    Отлично, спасибо! Хорошо, я пока не соглашусь ответить на этот вопрос, и если никто другой не придет, я приму его снова после тестирования вашего исправления :) – David Planella 31 May 2012 в 16:28

Я не знаю приятного ответа, но у меня есть работа для вас:

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

Это решение должно работать для других произвольных иерархий виджетов.

from gi.repository import Gtk

class NotebookWindow():
    def __init__(self):
        self.builder = Gtk.Builder()
        self.builder.add_from_file('notebook.ui')
        self.builder.get_object('window1').connect('delete-event',
            Gtk.main_quit)
        notebook = self.builder.get_object('notebook1')
        notebook.connect("switch-page", self.on_notebook1_switch_page)
        self.on_notebook1_switch_page(notebook, None,
                                      notebook.get_current_page())

    def on_notebook1_switch_page(self, widget, label, page):
        for p in range(widget.get_n_pages()):
            container = widget.get_nth_page(p)
            if not p == page:
                for c in container.get_children():
                    try:
                        c.hide_all()
                    except AttributeError:
                        c.hide()
            else:
                for c in container.get_children():
                    try:
                        c.show_all()
                    except AttributeError:
                        c.show()


if __name__ == '__main__':
    notebookwindow = NotebookWindow()
    Gtk.main()

В моем первоначальном ответе я записал и повторно установил требуемые размеры. Это вообще не работает, потому что запрошенный размер является минимальным. Я должен был бы записать максимальный размер, чтобы это работало.

3
ответ дан 18 August 2018 в 21:56
  • 1
    Это именно то, что мне нужно, спасибо! Я тестировал его для работы над rev 2 примера. Однако при тестировании с помощью реального кода он, похоже, не работал. Я отслеживал это потому, что виджеты в реальном приложении не помещаются непосредственно на страницу ноутбука, а скорее содержатся в сетке на каждой странице. Rev 3 примера иллюстрирует эту ситуацию. – David Planella 31 May 2012 в 15:37
  • 2
    Я соглашусь с ответом, так как это приемлемый способ решения вопроса. Тем не менее, я все еще придерживаюсь своего кода сеткой. Я не уверен в открытии нового вопроса, так как он будет слишком локализован, но в любом случае любые идеи, почему последний примерный код с сеткой не делает размер? Спасибо! – David Planella 31 May 2012 в 15:38
  • 3
    Привет, я подумаю об этом ... Но его всегда хорошо, когда вы подождете некоторое время, прежде чем принимать ответ, может быть, кто-то еще знает что-то лучше. Я думаю, что было бы разумнее отказаться от моего ответа, чем написать новый с небольшими изменениями. – xubuntix 31 May 2012 в 16:05
  • 4
    – xubuntix 31 May 2012 в 16:26
  • 5
    Отлично, спасибо! Хорошо, я пока не соглашусь ответить на этот вопрос, и если никто другой не придет, я приму его снова после тестирования вашего исправления :) – David Planella 31 May 2012 в 16:28

Другие вопросы по тегам:

Похожие вопросы: