使用CellRenderToggle创建Gtk3 Treeview,并使用Python从列表中选择名称

使用CellRenderToggle创建Gtk3 Treeview,并使用Python从列表中选择名称,python,gtk3,Python,Gtk3,我尝试创建一个Gtk.TreeView,其中包含列表中的标题名。因为我想以后用它来显示来自不同数据库的条目 问题是: 当我点击一个单元格并尝试激活它时,行中的所有单元格都会被激活。更奇怪的是,只有当我将光标移到它们上面(而不是单击)时,它们看起来才处于未激活状态 这个代码有什么问题 #!/usr/bin/env python #-*- coding: utf-8 -*- import gi gi.require_version('Gtk', '3.0') from gi.repository

我尝试创建一个Gtk.TreeView,其中包含列表中的标题名。因为我想以后用它来显示来自不同数据库的条目

问题是: 当我点击一个单元格并尝试激活它时,行中的所有单元格都会被激活。更奇怪的是,只有当我将光标移到它们上面(而不是单击)时,它们看起来才处于未激活状态

这个代码有什么问题

#!/usr/bin/env python
#-*- coding: utf-8 -*-

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


class CellRendererToggleWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="CellRendererToggle Example")
        self.set_default_size(400, 200)
        self.mainbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing = 10)
        self.add(self.mainbox)

        self.myliststore = Gtk.ListStore(bool,bool,str)
        self.treeview = Gtk.TreeView(self.myliststore)

        for n, header_text in enumerate(["Aktive", "Warning", "Text"]):
            if header_text in ["Aktive", "Warning"]:
                cell = Gtk.CellRendererToggle()
                cell.connect("toggled", self.on_sync_treeview_button_toggled, n, header_text )
                column = Gtk.TreeViewColumn(header_text, cell)
            else:
                cell = Gtk.CellRendererText()
                cell.set_property('editable', True)
                column = Gtk.TreeViewColumn(header_text, cell, text=n)
            column.set_sort_column_id(n)
            self.treeview.append_column(column)
        self.myliststore.append([True, True, "Super6!"])
        self.myliststore.append([True, True, "Super7!"])
        self.myliststore.append([True, True, "Super8!"])
        self.mainbox.pack_start(self.treeview, True, True, 0)

    def on_sync_treeview_button_toggled(self, widget, path, column, data):
        widget.set_active( [True,False][widget.get_active()] )


win = CellRendererToggleWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

“选择单元格”的概念在
GtkTreeView
中没有真正实现。如果您查看一下TreeView的所有可用函数,很少有函数真正针对单个单元格

这就给您留下了以下选项:

  • 实现您自己的“单个单元格”高亮显示(例如添加边框或更改背景颜色,例如通过添加额外的列来更改单元格的属性)

  • 使用
    Gtk.Grid
    ,其中“粒度”是一个单元格,但没有列标题的精确性,并且有一个很好的模型来加载数据

  • 高亮显示单元格(行已高亮显示)的另一种解决方案是更改相应列标题的颜色(或其他属性)


  • 没有一个选项是真正有吸引力的,并且每个方法都需要一些工作。

    TreeView列需要一个属性,用于“活动”并在存储中显示位置:

    column.add_attribute(cell, "active", n)
    
    我还必须更改底层存储,而不是小部件:

    self.myliststore[path][column] = not self.myliststore[path][column]
    
    感谢您的示例:

    现在它正在工作:

    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    from gi.repository import Gdk
    
    
    class CellRendererToggleWindow(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="CellRendererToggle Example")
            self.set_default_size(400, 200)
            self.mainbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing = 10)
            self.add(self.mainbox)
    
            self.myliststore = Gtk.ListStore(bool,bool,str)
            self.treeview = Gtk.TreeView(self.myliststore)
    
            for n, header_text in enumerate(["Aktive", "Warning", "Text"]):
                if header_text in ["Aktive", "Warning"]:
                    cell = Gtk.CellRendererToggle()
                    cell.connect("toggled", self.on_sync_treeview_button_toggled, n, header_text )
                    column = Gtk.TreeViewColumn(header_text, cell)
                    column.add_attribute(cell, "active", n)
    
                else:
                    cell = Gtk.CellRendererText()
                    cell.set_property('editable', True)
                    column = Gtk.TreeViewColumn(header_text, cell, text=n)
                column.set_sort_column_id(n)
                self.treeview.append_column(column)
            self.myliststore.append([True, False, "Super6!"])
            self.myliststore.append([True, True, "Super7!"])
            self.myliststore.append([False, True, "Super8!"])
            self.mainbox.pack_start(self.treeview, True, True, 0)
    
        def on_sync_treeview_button_toggled(self, widget, path, column, data):
            self.myliststore[path][column] = not self.myliststore[path][column]
    
    
    win = CellRendererToggleWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()