【问题标题】:Python Gtk3 TreeView TreeViewColumn truncating text with an ellipsis?Python Gtk3 TreeView TreeViewColumn用省略号截断文本?
【发布时间】:2021-10-16 01:26:24
【问题描述】:

我有一个 Gtk.TreeView 和一个 Gtk.ListStore 列。

给定一个任意大小的窗口,可由用户更改,具有可调整大小的“名称”列,所有其他列的大小固定 ~

我想要发生的是,当一个超宽的名称字符串被插入到列表中时,它的文本被截断,理想情况下添加一个省略号'...'。当窗口重新调整大小时,额外的周长可以显示更多的名称。但在任何时候都不需要 h-scroll。

现在发生的情况是,超宽文本只会将其他列推到右侧。这看起来很愚蠢。如果我阻止 h-scrolling,父窗口宽度会自动增加 - 在 已经全屏窗口上看起来不太好。

我不想使用 simple 固定像素宽度列作为名称,因为真正的对话需要根据其父级调整大小,而父级也需要调整到用户屏幕的大小。所以固定的像素大小几乎总是错误的。

我想要某种不激活 h-scroll 的解决方案。

任何类似:

  • 将“名称”字段截断,这样剩下的任何内容都“适合”而无需 h 滚动。
  • 不知何故检测到名称不合适,修剪它并添加省略号(可能是挂钩窗口调整大小)
  • 获取要包含在列中的名称(最后的手段)

到目前为止,我已经尝试了 SO 和其他许多地方建议的所有内容。总是找到非 python 文档和不同的 Gtk 版本的组合确实妨碍了理解。参考:Python GTK3 Doco

编辑:找到Gtk.TreeViewColumn.set_expand() 函数。所以现在 name 列扩展为额外的空间。

import sys
import gi

gi.require_version("Gtk", "3.0")
gi.require_version("Gdk", "3.0")

from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf



class ListWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="List Demo")
        self.set_border_width( 10 )
        self.set_default_size( 400, 300 )

        header = Gtk.HeaderBar(title="List Demo")
        header.props.show_close_button = True
        self.set_titlebar(header)

        self.scrollable = Gtk.ScrolledWindow()
        self.scrollable.set_policy( Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC )

        self.colour_list = Gtk.ListStore( str, int, int, int, GdkPixbuf.Pixbuf )
        self.tree_view = Gtk.TreeView( model=self.colour_list )
        self.tree_view.set_headers_visible( True )

        # For right-justifying columnms
        right_justify = Gtk.CellRendererText()
        right_justify.set_alignment( 1.0, 0.5 )  # right, centre

        # Five columns, name, r, g, b, swatch
        column1 = Gtk.TreeViewColumn( "Name",   Gtk.CellRendererText(), text=0 )
        column2 = Gtk.TreeViewColumn( "Red",    right_justify, text=1 )
        column3 = Gtk.TreeViewColumn( "Grn",    right_justify, text=2 )
        column4 = Gtk.TreeViewColumn( "Blu",    right_justify, text=3 )
        column5 = Gtk.TreeViewColumn( "Swatch", Gtk.CellRendererPixbuf(), pixbuf=4)

        columns = [ column1, column2, column3, column4, column5 ]

        for i,col in enumerate( columns ):
            if ( i == 0 ):
                col.set_sizing( Gtk.TreeViewColumnSizing.AUTOSIZE )  # all columns except first fixed size
                col.set_expand( True )
                col.set_resizable( True )
            else:
                col.set_sizing( Gtk.TreeViewColumnSizing.FIXED )  
                col.set_expand( False )
                col.set_resizable( False )
            self.tree_view.append_column( col )

        self.populateList()

        # FInally add everything to the window
        self.scrollable.add( self.tree_view )
        self.add( self.scrollable )
        self.show_all()


    def getColouredPixmap( self, r, g, b, a=255 ):
        """ Given components, return a colour swatch pixmap """
        CHANNEL_BITS=8
        WIDTH=64
        HEIGHT=32
        swatch = GdkPixbuf.Pixbuf.new( GdkPixbuf.Colorspace.RGB, True, CHANNEL_BITS, WIDTH, HEIGHT ) 
        swatch.fill( (r<<24) | (g<<16) | (b<<8) | a ) # RGBA
        return swatch


    def populateList( self ):
        """ Fill the list with a number of colour-name, components and swatch-image """
        # Probematic Record for the top entry
        swatch = self.getColouredPixmap( 184, 134,  11 )
        #self.colour_list.append( [ 'Sarcoline (literally mea…', 184, 134,  11, swatch ] )
        self.colour_list.append( [ 'Sarcoline (literally meaning: "flesh coloured", so varies...)', 184, 134,  11, swatch ] )

        # A bunch of other records, just for fun
        try:
            fin = open( '/etc/X11/rgb.txt', 'rt' )
            records = fin.readlines()
            fin.close()
        except:
            # excerpt fro those without rgb.txt
            records = """ 245 255 250     MintCream
                          240 255 255     azure
                          240 248 255     alice blue
                          230 230 250     lavender
                          255 240 245     lavender blush """.split( '\n' )

        # 255 240 245     lavender blush
        for rec in records:
            if ( len( rec.strip() ) > 0 and rec[0] != '!' and rec.find('gray') == -1 ):
                rec = rec.strip().replace( '\t', ' ')
                while( rec.find( '  ' ) != -1 ):
                    rec = rec.replace( '  ', ' ' )  # remeove double-spaces
                r,g,b,desc = rec.split( ' ', 3 )
                r = int( r )
                g = int( g )
                b = int( b )
                swatch = self.getColouredPixmap( r, g, b )
                self.colour_list.append( [ desc.capitalize(), r, g, b, swatch ] )


### MAIN
win = ListWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

【问题讨论】:

    标签: python treeview gtk3


    【解决方案1】:

    显式设置GtkCellRendererText"ellipsize" 属性似乎有效:

            renderer  = Gtk.CellRendererText()
            renderer.set_property("ellipsize", Pango.EllipsizeMode.END)
            # Five columns, name, r, g, b, swatch
            column1 = Gtk.TreeViewColumn( "Name",   renderer, text=0 )
    

    您可能也对preventing last column from growing感兴趣

    【讨论】:

    • 别忘了from gi.repository import Pango
    • 感谢您的回答,现在我知道怎么做很容易。我只需要猜测搜索“椭圆”这个词。我想知道为什么这个函数没有被提升为TreeViewColumn 成员函数,它对于处理表格数据非常重要。