如何将“隐藏数据”分配给 Gtk.TreeView 行以便用 Gtk.TreeView.connect("row-activated") 捕获它们?

How to assign “hidden data” to Gtk.TreeView row in order to catch them with Gtk.TreeView.connect("row-activated")?

在 Python 中,我有一个 class person 包含 firstNamelastName 以及 country 属性(实际上他们是更多其他数据,但我简化了它作为示例)。

所以,我生成一个table 应该只显示firstNamelastName(用户不应该看到国家)。但是当用户点击特定行时,我想获得完整的 person 对象。

这是我的代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# MWE for hidden data in Gtk.TreeView

import sys
import os
import gi

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Gio
from gi.repository import Pango


class person():
    def __init__(self, firstName, lastName, country):
        self.firstName=firstName
        self.lastName=lastName
        self.country=country

personsList=[
    person("Ada",   "Lovelace", "UK"),
    person("Alan",  "Turing",   "UK"),
    person("Denis", "Richie",   "USA")
]

def onRowChange(widget, row, col):
    # This function is executed when a user click on a row
    print(widget)
    print(row)
    print(col)
    pass


class GridWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="TreeView MWE")
        self.connect("destroy", Gtk.main_quit)

        # Setting up the self.grid in which the elements are to be positionned
        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)

        # Preparing the list store
        listStore=Gtk.ListStore(str, str)
        for aPerson in personsList:
            listStore.append([aPerson.firstName, aPerson.lastName])

        # Seting up the TreeView and given the ListStore to the Treeview
        treeView=Gtk.TreeView(model=listStore)
        renderer_text = Gtk.CellRendererText()

        # Preparing the headers
        column_text = Gtk.TreeViewColumn("First Name", renderer_text, text=0)
        treeView.append_column(column_text)
        column_text = Gtk.TreeViewColumn("Last Name", renderer_text, text=1)
        treeView.append_column(column_text)

        # Setting the event connection
        treeView.connect("row-activated", onRowChange)


        # Attaching the treeView to the Gride
        self.grid.add(treeView)




screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()


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

这是效果图:

可以看到,根据row_activated信号的,onRowChange()函数在用户点击的时候只能得到TreeViewTreeViewColumn对象文档。

我知道我可以获得行号并在列表中搜索 对象有这个行号但是它太危险而且有点 hacky.

那么,他们是否可以将用户的隐藏数据包含在 Gtk.ListStore 中并使用 row-activated 信号捕获该数据?

您可以只将数据添加到您的列表存储中,而无需在树视图中显示。 以下代码片段显示了必要的更改:

...
def onRowChange(widget, row, col):
    # This function is executed when a user click on a row
    model = widget.get_model()
    iter_ = model.get_iter(row)
    person = model.get_value(iter_, 2)
    print(person.country)


class GridWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="TreeView MWE")
        self.connect("destroy", Gtk.main_quit)

        # Setting up the self.grid in which the elements are to be positionned
        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)

        # Preparing the list store
        listStore=Gtk.ListStore(str, str, object)
        for aPerson in personsList:
            listStore.append([aPerson.firstName, aPerson.lastName, aPerson])
...

请尝试下面的示例。一些原始代码被注释掉,下面是用#*** 突出显示的替换代码。

单击一行时,控制台应显示包含三个字段(名字、姓氏和国家/地区)的列表。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# MWE for hidden data in Gtk.TreeView

import sys
import os
import gi

gi.require_version('Gtk', '3.0')

from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import Gio
from gi.repository import Pango


class person():
    def __init__(self, firstName, lastName, country):
        self.firstName=firstName
        self.lastName=lastName
        self.country=country

personsList=[
    person("Ada",   "Lovelace", "UK"),
    person("Alan",  "Turing",   "UK"),
    person("Denis", "Richie",   "USA")
]

#*** Instead use: def on_row_activated(self, widget, row, col_view):
#def onRowChange(widget, row, col):
#    # This function is executed when a user click on a row
#    print(widget)
#    print(row)
#    print(col)
#    pass


class GridWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="TreeView MWE")
        self.set_size_request(200,150)
        self.connect("destroy", Gtk.main_quit)

        # Setting up the self.grid in which the elements are to be positionned
        self.grid = Gtk.Grid()
        self.grid.set_column_homogeneous(True)
        self.grid.set_row_homogeneous(True)
        self.add(self.grid)

        # Preparing the list store
        #listStore=Gtk.ListStore(str, str)
        #*** Increase to three strings
        listStore=Gtk.ListStore(str, str, str)
        for aPerson in personsList:
            #listStore.append([aPerson.firstName, aPerson.lastName])
            #*** Add the country
            listStore.append([aPerson.firstName, aPerson.lastName, aPerson.country])
            
        # Seting up the TreeView and given the ListStore to the Treeview
        treeView=Gtk.TreeView(model=listStore)
        renderer_text = Gtk.CellRendererText()

        # Preparing the headers
        column_text = Gtk.TreeViewColumn("First Name", renderer_text, text=0)
        treeView.append_column(column_text)
        column_text = Gtk.TreeViewColumn("Last Name", renderer_text, text=1)
        treeView.append_column(column_text)

        # Setting the event connection
        #treeView.connect("row-activated", onRowChange)
        #*** Change connection so double-clicking on row calls self.on_row_activated
        treeView.connect("row-activated", self.on_row_activated)

        # Attaching the treeView to the Grid
        self.grid.add(treeView)

    #*** Change to using this callback when a row is double-clicked.
    def on_row_activated(self, widget, row, col_view):
        """ Calllback for double-click on Treeview row"""
        model = widget.get_model()
        row_list = []
        for i in range(model.get_n_columns()):
            #print(model[row][i])
            row_list.append(model[row][i])
        print(row_list)   
        
        # Example of what the console displays upon double-clicking a row...
        # ['Alan', 'Turing', 'UK']
        # ['Denis', 'Richie', 'USA']

screen = Gdk.Screen.get_default()
styleContext = Gtk.StyleContext()


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