{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# GTK4 spreadsheet\n\nExample of embedding Matplotlib in an application and interacting with a\ntreeview to store data. Double-click on an entry to update plot data.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import gi\n\ngi.require_version('Gtk', '4.0')\ngi.require_version('Gdk', '4.0')\nfrom gi.repository import Gtk\n\nfrom numpy.random import random\n\nfrom matplotlib.backends.backend_gtk4agg import FigureCanvas # or gtk4cairo.\nfrom matplotlib.figure import Figure\n\n\nclass DataManager(Gtk.ApplicationWindow):\n num_rows, num_cols = 20, 10\n\n data = random((num_rows, num_cols))\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.set_default_size(600, 600)\n\n self.set_title('GtkListStore demo')\n\n vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, homogeneous=False,\n spacing=8)\n self.set_child(vbox)\n\n label = Gtk.Label(label='Double click a row to plot the data')\n vbox.append(label)\n\n sw = Gtk.ScrolledWindow()\n sw.set_has_frame(True)\n sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)\n sw.set_hexpand(True)\n sw.set_vexpand(True)\n vbox.append(sw)\n\n model = self.create_model()\n self.treeview = Gtk.TreeView(model=model)\n self.treeview.connect('row-activated', self.plot_row)\n sw.set_child(self.treeview)\n\n # Matplotlib stuff\n fig = Figure(figsize=(6, 4), layout='constrained')\n\n self.canvas = FigureCanvas(fig) # a Gtk.DrawingArea\n self.canvas.set_hexpand(True)\n self.canvas.set_vexpand(True)\n vbox.append(self.canvas)\n ax = fig.add_subplot()\n self.line, = ax.plot(self.data[0, :], 'go') # plot the first row\n\n self.add_columns()\n\n def plot_row(self, treeview, path, view_column):\n ind, = path # get the index into data\n points = self.data[ind, :]\n self.line.set_ydata(points)\n self.canvas.draw()\n\n def add_columns(self):\n for i in range(self.num_cols):\n column = Gtk.TreeViewColumn(str(i), Gtk.CellRendererText(), text=i)\n self.treeview.append_column(column)\n\n def create_model(self):\n types = [float] * self.num_cols\n store = Gtk.ListStore(*types)\n for row in self.data:\n # Gtk.ListStore.append is broken in PyGObject, so insert manually.\n it = store.insert(-1)\n store.set(it, {i: val for i, val in enumerate(row)})\n return store\n\n\ndef on_activate(app):\n manager = DataManager(application=app)\n manager.show()\n\n\napp = Gtk.Application(application_id='org.matplotlib.examples.GTK4Spreadsheet')\napp.connect('activate', on_activate)\napp.run()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.2"
}
},
"nbformat": 4,
"nbformat_minor": 0
}