fauve
fauve

Reputation: 243

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

In Python, I have a class person witch contain firstName and lastName and also country attributes (actually their is much more other data, but I simplify it for the example).

So, I generate a table witch should only show firstName and lastName (the user shouldn’t see the country). But when the user click on a specific row, I want to get the the full person object.

This is my code:

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

And here is the rendering:

enter image description here

As you can see, the onRowChange() function can only get the TreeView and the TreeViewColumn objects when the user click on it, according to the row_activated signal’s documentation.

I know I can get the row number and search in the list witch object has this row number but it’s too much hazardous and a little bit hacky.

So, is their a way to include in the Gtk.ListStore a user’s hidden data and catch back this data with row-activated signal?

Upvotes: 0

Views: 815

Answers (2)

irs
irs

Reputation: 96

Please try the example below. Some of the original code is commented out and below it is replacement code highlighted with #***.

On clicking on a row the console should display a list containing the three fields (firstname, surname and country).

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

Upvotes: 0

elya5
elya5

Reputation: 2258

You can just add data to your liststore without showing it in the treeview. The following code snippet shows the necessary changes:

...
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])
...

Upvotes: 0

Related Questions