python-3.x 将Gtk.TreeView添加到Gtk.ScrolledWindow时,滚动条光标超出比例

kcugc4gi  于 2023-05-19  发布在  Python
关注(0)|答案(1)|浏览(103)

如果我想使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)

ScrollledWindow本身被打包到Gtk. Grid中。
我怀疑滚动条中有一个属性指定了最小大小,并试图修改页面大小-再次没有运气。
这里有一个完整的最小例子。MainWindow中的if True可以更改为False,以启用/禁用ScrollWindow的使用。在create_segment_table中提到vadj的三行可以被注解掉,以禁用我的页面大小限制实验。

#!/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
        )
2ul0zpep

2ul0zpep1#

当然,这里的问题是滚动条的滑块太大了,以至于不能移动。为了解决这个问题,您需要更改滑块的最小高度。如果滑块可以更小,它将有更多的空间来移动。

创建CSS

您可以使用CSS更改滑块的最小高度。但是,如果更改 * 滑块的 * 高度,则还需要更改 * 槽的 * 高度。如果不这样做,ScrolledWindow将缩小以适应滑块,您将返回到开始的位置。
创建一个CSS文件,并将其放入其中:

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

这会将滑块的最小高度设置为10像素,将槽的最小高度设置为50像素。这确保滑块有足够的空间在槽中移动,即使在最低高度。您可以根据自己的喜好调整这些值。

加载CSS

现在你只需要加载CSS。为此,您可以使用Gtk.CSSProviderGtk.StyleContext

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
)

请注意,您必须导入Gdk才能使其工作。

完整示例

下面是一个完整的可复制的例子,使用您的代码:

#!/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))

请注意,我删除了试图更改页面大小的代码,因为它不是解决方案的一部分。我希望这对你有帮助!

相关问题