При добавлении Gtk.TreeView в Gtk.ScrolledWindow курсор полосы прокрутки выходит за пределы масштаба.

Если я хочу сделать Gtk.TreeView прокручиваемым, я встраиваю его в Gtk.ScrolledWindow. Встраивание TreeView приводит к тому, что курсор выходит за рамки масштаба (слишком большой).

В TreeView есть еще 7 строк ниже показанных 3. Я ожидаю, что курсор полосы прокрутки масштабируется до 1/3, что позволит мне комфортно прокручивать.

Я могу нормально прокручивать колесо прокрутки мыши и прокручивать клавиши со стрелками на клавиатуре.

Это код, который создает TextView:

              self.segment_store = Gtk.ListStore(str, str, str, str, str, str)
        self.segment_view = Gtk.TreeView(model = self.segment_store,
                    hexpand = True)
        
        self.segment_scroller = Gtk.ScrolledWindow()
        self.segment_scroller.add(self.segment_view)

Сам ScrolledWindow упакован в Gtk.Grid.

Я подозревал, что в полосе прокрутки есть свойство, определяющее минимальный размер, и попытался изменить размер страницы — опять безуспешно.

Вот полный минимальный пример. if Trueв MainWindow можно изменить на False, чтобы включить/отключить использование ScrollWindow. Три строки, в которых упоминается Ваджcreate_segment_tableможно закомментировать, чтобы отключить мой эксперимент по ограничению размера страницы.

      #!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#  test_embedded_treeview.py
#
#  Copyright 2023 John Coppens <john@jcoppens.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class MainWindow(Gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.connect("destroy", lambda x: Gtk.main_quit())
        self.set_default_size(400, 300)

        self.create_segment_table()
        for i in range(10):
            self.segment_store.append( ('0', )*6 )

        if True:
            grid = Gtk.Grid()
            grid.attach(self.segment_scroller, 1, 1, 1, 1)

            self.add(grid)
        else:
            self.add(self.segment_scroller)

        self.show_all()

    def run(self):
        Gtk.main()


    def create_segment_table(self):
        self.segment_store = Gtk.ListStore(str, str, str, str, str, str)
        self.segment_view = Gtk.TreeView(model = self.segment_store,
                    hexpand = True)
        #   La tabla puede crecer demasiado, asi que agregamos un 'scroller'
        self.segment_scroller = Gtk.ScrolledWindow()
        self.segment_scroller.add(self.segment_view)

        # Trying to change the page size of the scrollbar
        vadj = self.segment_scroller.get_vadjustment()
        vadj.set_page_size(20)
        self.segment_scroller.set_vadjustment(vadj)

        # Creamos las columnas para la tabla
        for colnr, header in enumerate( ('X0', 'Y0', 'Z0', 'X1', 'Y1', 'Z1') ):
            renderer = Gtk.CellRendererText(editable = True)
            # ~ renderer.connect('edited', self.on_cell_edited, colnr)
            col = Gtk.TreeViewColumn(header, renderer, text = colnr)
            col.set_expand(True)
            self.segment_view.append_column(col)


def main(args):
    mainwdw = MainWindow()
    mainwdw.run()

    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

РЕДАКТИРОВАТЬ: отличный ответ Сильвестра ниже — отличное решение этой проблемы. Поскольку это исправление недостатка виджета, а не проблема стиля, я решил не использовать внешний файл .CSS, который несколько усложнил бы обслуживание. Поэтому я включил CSS в сам код (обратите внимание, чтоload_from_dataтребуется строка байтов):

              style_provider = Gtk.CssProvider()
        style_provider.load_from_data(b"slider {min-height: 10px; }"
                                      b"trough {min-height: 50px; }")

        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(),
            style_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_USER
        )

1 ответ

Проблема здесь, конечно, в том, что ползунок полосы прокрутки настолько велик, что его невозможно переместить. Чтобы это исправить, вам нужно изменить минимальную высоту ползунка. Если ползунок будет меньше, у него будет больше места для перемещения.

Создание CSS

Вы можете использовать CSS, чтобы изменить минимальную высоту ползунка. Однако если вы измените высоту ползунка , вам также потребуется изменить высоту желоба . Если вы этого не сделаете,просто уменьшится до размера ползунка, и вы вернетесь к тому, с чего начали.

Итак, создайте файл CSS и поместите туда это:

      slider {
    min-height: 10px;
}
trough {
    min-height: 50px;
}

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

Загрузка CSS

Теперь вам просто нужно загрузить CSS. Для этого вы можете использоватьи:

      style_provider = Gtk.CssProvider()
style_provider.load_from_path("/path/to/theme.css")

Gtk.StyleContext.add_provider_for_screen(
    Gdk.Screen.get_default(),
    style_provider,
    Gtk.STYLE_PROVIDER_PRIORITY_USER
)

Обратите внимание, что вам придется импортироватьдля того, чтобы это работало.

Полный пример

Вот полный воспроизводимый пример с использованием вашего кода:

      #!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#  test_embedded_treeview.py
#
#  Copyright 2023 John Coppens <john@jcoppens.com>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA 02110-1301, USA.
#
#


import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk # Import Gdk
from gi.repository import Gtk

class MainWindow(Gtk.Window):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.connect("destroy", lambda x: Gtk.main_quit())
        self.set_default_size(400, 300)

        self.create_segment_table()
        for i in range(10):
            self.segment_store.append( ('0', )*6 )

        ######################################
        # Load the CSS to change the slider
        style_provider = Gtk.CssProvider()
        style_provider.load_from_path("/path/to/theme.css")

        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(),
            style_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_USER
        )

        ######################################

        if True:
            grid = Gtk.Grid()
            grid.attach(self.segment_scroller, 1, 1, 1, 1)

            self.add(grid)
        else:
            self.add(self.segment_scroller)

        self.show_all()

    def run(self):
        Gtk.main()


    def create_segment_table(self):
        self.segment_store = Gtk.ListStore(str, str, str, str, str, str)
        self.segment_view = Gtk.TreeView(model = self.segment_store,
                    hexpand = True)
        #   La tabla puede crecer demasiado, asi que agregamos un 'scroller'
        self.segment_scroller = Gtk.ScrolledWindow()
        self.segment_scroller.add(self.segment_view)

        # Creamos las columnas para la tabla
        for colnr, header in enumerate( ('X0', 'Y0', 'Z0', 'X1', 'Y1', 'Z1') ):
            renderer = Gtk.CellRendererText(editable = True)
            # ~ renderer.connect('edited', self.on_cell_edited, colnr)
            col = Gtk.TreeViewColumn(header, renderer, text = colnr)
            col.set_expand(True)
            self.segment_view.append_column(col)


def main(args):
    mainwdw = MainWindow()
    mainwdw.run()

    return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

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

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