diff --git a/README.md b/README.md index 50be6d1..15849a0 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Topics covered: - Setting the cursor - Setting dark colour theme - Spacing and padding + - Selection Grid - Custom drawing with Snapshot For beginners, I suggest walking through each example and try to understand what each line is doing. I also recommend taking a look at the docs for each widget. @@ -765,6 +766,77 @@ margin to our **box** layout. ![Spacing and padding](spacing.png) +# Using GridView + +Here Ill show a [***GridView***](https://docs.gtk.org/gtk4/class.GridView.html). The setup is similar for other wigets like ListView and ColumnsView. + +![GridView](grid.png) + +First lets make a GridView and attatch it to our second vert box. + +```python + + self.grid1 = Gtk.GridView() + self.box3.append(self.grid1) + + fruits = ["Banana", "Apple", "Strawberry", "Pear", "Watermelon", "Blueberry"] +``` + +That part was easy! But it gets a little more complicated from here. In order for these kinds of widgets to work we need two things, a **model** and a **factory**. + +Lets start with the **model**. The model will hold the basis for the information we want in each item in the grid. + +First we can create an object that will hold the data we want for each item in the list/grid. + +```python + class Fruit(GObject.Object): + name = GObject.Property(type=str) + def __init__(self, name): + super().__init__() + self.name = name +``` + +Then we create each object and put them in a ListStore. Then from that ListStore we create a SelectionModel, in this case im using a *SingleSelection*. + +Then we set that selection model as the model for the grid. + +```python + self.ls = Gio.ListStore() + + for f in fruits: + self.ls.append(Fruit(f)) + + ss = Gtk.SingleSelection() + ss.set_model(self.ls) + + self.grid1.set_model(ss) +``` + +Next we need a **factory**. The factory is what creates the widgets in the grid for each item in the model. + +```python + factory = Gtk.SignalListItemFactory() + + def f_setup(fact, item): + label = Gtk.Label(halign=Gtk.Align.START) + label.set_selectable(False) + item.set_child(label) + + factory.connect("setup", f_setup) + + def f_bind(fact, item): + item.get_child().set_label(item.get_item().name) + + factory.connect("bind", f_bind) + + self.grid1.set_factory(factory) + +``` + +That should then work. To get the selected item in the grid: + + + # Custom drawing with Snapshot As mentioned in the Cairo section, Snapshot uses fast hardware accelerated drawing, but it's a little more complicated to diff --git a/grid.png b/grid.png new file mode 100644 index 0000000..fc3c6df Binary files /dev/null and b/grid.png differ diff --git a/part1.py b/part1.py index f30da99..d3acbdd 100644 --- a/part1.py +++ b/part1.py @@ -3,7 +3,7 @@ import gi gi.require_version('Gtk', '4.0') gi.require_version('Adw', '1') -from gi.repository import Gtk, Adw +from gi.repository import Gtk, Adw, Gio, GObject class MainWindow(Gtk.ApplicationWindow): @@ -22,6 +22,52 @@ class MainWindow(Gtk.ApplicationWindow): self.box1.append(self.box2) # Put vert box in that box self.box1.append(self.box3) # And another one, empty for now + self.grid1 = Gtk.GridView() + self.box3.append(self.grid1) + + fruits = ["Banana", "Apple", "Strawberry", "Pear", "Watermelon", "Blueberry"] + + class Fruit(GObject.Object): + name = GObject.Property(type=str) + def __init__(self, name): + super().__init__() + self.name = name + + self.ls = Gio.ListStore() + + for f in fruits: + self.ls.append(Fruit(f)) + + ss = Gtk.SingleSelection() + ss.set_model(self.ls) + + self.grid1.set_model(ss) + + factory = Gtk.SignalListItemFactory() + def f_setup(fact, item): + label = Gtk.Label(halign=Gtk.Align.START) + label.set_selectable(False) + item.set_child(label) + + factory.connect("setup", f_setup) + + def f_bind(fact, item): + item.get_child().set_label(item.get_item().name) + + factory.connect("bind", f_bind) + + self.grid1.set_factory(factory) + + print(ss.get_selected_item().name) + + def on_selected_items_changed(selection, position, n_items): + selected_item = selection.get_selected_item() + if selected_item is not None: + print(f"Selected item changed to: {selected_item.name}") + + ss.connect("selection-changed", on_selected_items_changed) + + # Add a button self.button = Gtk.Button(label="Hello") self.button.connect('clicked', self.hello)