在Gtk.Treeview中识别被单击的列

编程语言 2026-07-08

我一直在尝试获取在Gtk.Treeview中被单击的那一列的列号/列ID(用Python编写……但这其实并不重要)。

我查看了以下站点:

https://docs.gtk.org/gtk3/method.TreeView.set_headers_clickable.html

GtkTreeView列头单击事件

https://docs.gtk.org/gtk3/class.TreeViewColumn.html

https://docs.gtk.org/gtk3/method.TreeViewColumn.clicked.html

它们似乎都表示只能得到get_sort_column_id()。但我并不想排序,我只想运行一些代码来识别被单击的列的编号。参考以下文章的代码:https://python-gtk-3-tutorial.readthedocs.io/en/latest/treeview.html,我能够展示列的各种属性,但没有列号。我应该如何实现?谢谢。

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
software_list = [("Firefox", 2002, "C++"),("Eclipse", 2004, "Java")]
class TreeViewFilterWindow(Gtk.Window):
    def __init__(self):
        super().__init__()
        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.set_default_size(500,200)
        self.add(self.grid)
        self.software_liststore = Gtk.ListStore(str, int, str)
        for software_ref in software_list:
            self.software_liststore.append(list(software_ref))
        self.current_filter_language = None
        self.treeview = Gtk.TreeView(model=self.software_liststore)
        for i, column_title in enumerate(["SW", "Year", "Language"]):
            renderer = Gtk.CellRendererText()
            column = Gtk.TreeViewColumn(column_title, renderer, text=i)
            self.treeview.append_column(column)
########
# This allows the column to be clicked, but how do I identify, whick column I clicked? 
            self.treeview.set_headers_clickable(True) # Probably not necessary
            column.set_sort_column_id(True)                    # LINE A
            column.set_clickable(True)
            column.connect('clicked', self.column_id, column)
########
        self.scrollable_treelist = Gtk.ScrolledWindow()
        self.grid.attach(self.scrollable_treelist, 0, 0, 8, 10)
        self.scrollable_treelist.add(self.treeview)
        self.show_all()

    def column_id(self, widget, column):
       # This prints the selected column
       print('selected column', column)
       # This only shows -1 or 1 depending if LINE A is present or not
       print(column.get_sort_column_id())
       # This attribute, I was hoping, would show me the column number
       # but it does not:
       print(column.get_column_id())

win = TreeViewFilterWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

解决方案

我不确定,但 TreeViewColumn 可能是一个独立对象,且在 Treeview 中可能不知道它自己的编号。

但在Python中,你总是可以自己定义变量

column.my_number = i

然后你可以在函数中得到这个 column.my_number

print(column.my_number)

顺便说一句:

文档显示你可以使用

column.set_data("my_number", i)
i = column.get_data("my_number")

但它会报错,并且建议使用普通的

column.my_number = i
i = column.my_number

你不必把 column 发送给 column_id(...),因为你已经在 widget 中拿到了它

print(widget.my_number)

但也许你应该传递数字而不是列

column.connect('clicked', self.column_id, i)
def column_id(self, widget, number):

看起来你也可以向 treeview 询问列/控件的索引

index = self.treeview.get_columns().index(widget)

并获取此列中的所有值

values = [row[index] for row in self.software_liststore]
#values = [row[widget.my_nymber] for row in self.software_liststore]

用于测试的完整代码:

import gi

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

software_list = [("Firefox", 2002, "C++"), ("Eclipse", 2004, "Java")]


class TreeViewFilterWindow(Gtk.Window):
    def __init__(self):
        super().__init__()
        self.set_default_size(500, 200)

        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)

        self.software_liststore = Gtk.ListStore(str, int, str)
        for software_ref in software_list:
            self.software_liststore.append(list(software_ref))

        self.current_filter_language = None

        self.treeview = Gtk.TreeView(model=self.software_liststore)
        self.treeview.set_headers_clickable(True)  # Probably not necessary

        for i, column_title in enumerate(["SW", "Year", "Language"]):
            renderer = Gtk.CellRendererText()
            column = Gtk.TreeViewColumn(column_title, renderer, text=i)

            # This allows the column to be clicked, but how do I identify, whick column I clicked?
            column.set_sort_column_id(True)
            column.set_clickable(True)
            column.connect("clicked", self.column_id)
            column.my_number = i
            # column.set_data("column-id", i)  # it suggests to set `column.column_id = i`

            self.treeview.append_column(column)

        ########
        self.scrollable_treelist = Gtk.ScrolledWindow()
        self.grid.attach(self.scrollable_treelist, 0, 0, 8, 10)
        self.scrollable_treelist.add(self.treeview)
        self.show_all()

    def column_id(self, widget):
        print("widget:", widget)

        print("title :", widget.get_title())
        print("my_number:", widget.my_number)
        # print("column-id:", widget.get_data("column-id"))  # it suggests to get `i = widget.column_id`

        index = self.treeview.get_columns().index(widget)
        print("index    :", index)

        values = [row[index] for row in self.software_liststore]
        print("values (index)    :", values)

        values = [row[widget.my_number] for row in self.software_liststore]
        print("values (my_number):", values)

        print("---")


win = TreeViewFilterWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

结果:

widget: <Gtk.TreeViewColumn object at 0x7cf60c6de180 (GtkTreeViewColumn at 0x29128d10)>
title : Language
my_number: 2
index    : 2
values (index)    : ['C++', 'Java']
values (my_number): ['C++', 'Java']
---
widget: <Gtk.TreeViewColumn object at 0x7cf60c6ddf40 (GtkTreeViewColumn at 0x291736d0)>
title : Year
my_number: 1
index    : 1
values (index)    : [2004, 2002]
values (my_number): [2004, 2002]
---
widget: <Gtk.TreeViewColumn object at 0x7cf60c6ddf80 (GtkTreeViewColumn at 0x291e5d30)>
title : SW
my_number: 0
index    : 0
values (index)    : ['Firefox', 'Eclipse']
values (my_number): ['Firefox', 'Eclipse']
---
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章