GTK + 3.0: How to use Gtk.TreeStore with custom model elements?

I am trying to develop a GTK application in Python, and I am really fixated on using gtk.TreeStore . My main problem: I already parsed some JSON, and I have my own data structure, which is basically a Python list and two types of objects: One is a collection of elements (collections cannot be nested) and one for representing elements (which may appear in a list as well as in a collection).

I am already familiar with the main uses of TreeStore and have the opportunity to correctly display elements on the screen. I don’t know how to cope with the fact that the treestore is only able to store gobject types (at the moment I’m not sure, because I know little about a system like gobject). The documentation for C lists the following (except PixBuf) base types that can be inserted and automatically mapped to Python data types:

As an example, gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING, GDK_TYPE_PIXBUF); will create a new GtkTreeStore with three columns of type int, string and GdkPixbuf respectively.

In addition, it says that you can insert GType . A link from the documentation directly points to this paragraph:

A numeric value that represents the unique identifier of a registered type.

My research on the topic ends here, and Google finds mostly GTK 2.x tutorials and nothing about inserting data types other than str and int , etc.
Questions:

  • Is it possible to implement a new GType (or any other interface that makes the insertion of user data into the treestore possible) and how to do it?
    I already tried to get GObject , but that didn't help.

  • How can I get rid of saving two data structures at the same time?
    Namely, my analysis result and duplicate information in Treestore.

  • How can you deal with mixed content?
    In my case, I have collections and elements with various additional information (which are reflected in the tree structure as nodes with or without children).

If the above issues are resolved, I also get rid of the problem when processing the choices: it is difficult to match a simple type, for example str or int , to match the element that I inserted before. Such an attribute should be the key, and you should still look for a list with analysis results that is inefficient.

Thank you in advance!

Additional information not directly related to the question:


I thought this could be a real task to implement a custom TreeModel until I read this in a tutorial for GTK 2 :

However, all this is expensive: you are unlikely to write a useful user model in less than a thousand lines if you do not split all the newline characters. Writing a custom model is not as difficult as it might sound, but it can be worth the effort, not least because it will lead to significantly more robust code if you have a lot of tracking data.

Is this still relevant?


I just stumbled upon http://www.pygtk.org/articles/subclassing-gobject/sub-classing-gobject-in-python.htm Could this be helpful? How many resoucres is for PyGTK 2.0. outdated.

+6
source share
1 answer

The problem is solved! For other people facing the same problem, I am accumulating several useful resources and my sample code. This is normal if you know how to do it, but it is not documented anywhere.

Fill in the sample code in order to have a TreeView filled with Faces and print the selected person with the click of a button:

 from gi.repository import Gtk from gi.repository import GObject class Person (GObject.GObject): name = GObject.property(type=str) age = GObject.property(type=int) gender = GObject.property(type=bool, default=True) def __init__(self): GObject.GObject.__init__(self) def __repr__(self): s = None if self.get_property("gender"): s = "m" else: s = "f" return "%s, %s, %i" % (self.get_property("name"), s, self.get_property("age")) class MyApplication (Gtk.Window): def __init__(self, *args, **kwargs): Gtk.Window.__init__(self, *args, **kwargs) self.set_title("Tree Display") self.set_size_request(400, 400) self.connect("destroy", Gtk.main_quit) self.create_widgets() self.insert_rows() self.show_all() def create_widgets(self): self.treestore = Gtk.TreeStore(Person.__gtype__) self.treeview = Gtk.TreeView() self.treeview.set_model(self.treestore) column = Gtk.TreeViewColumn("Person") cell = Gtk.CellRendererText() column.pack_start(cell, True) column.set_cell_data_func(cell, self.get_name) self.treeview.append_column(column) vbox = Gtk.VBox() self.add(vbox) vbox.pack_start(self.treeview, True, True, 0) button = Gtk.Button("Retrieve element") button.connect("clicked", self.retrieve_element) vbox.pack_start(button, False, False, 5) def get_name(self, column, cell, model, iter, data): cell.set_property('text', self.treestore.get_value(iter, 0).name) def insert_rows(self): for name, age, gender in [("Tom", 19, True), ("Anna", 35, False)]: p = Person() p.name = name p.age = age p.gender = gender self.treestore.append(None, (p,)) def retrieve_element(self, widget): model, treeiter = self.treeview.get_selection().get_selected() if treeiter: print "You selected", model[treeiter][0] if __name__ == "__main__": GObject.type_register(Person) MyApplication() Gtk.main() 
+11
source

Source: https://habr.com/ru/post/918878/


All Articles