Help with the behaviour of the CellRendererCombo on editable treeviews

Hello,

I’m working on an application that uses sometimes editable treeviews and I have stumbled upon an issue when using an editable Gtk.CellRenderCombo.

Once the cell is edited, a Combobox kicks in and its model is filled with options. Those options can vary according to other fields in the form.

The issue is that if a user edits the cell then click somewhere else on the form then the Combobox stays there. I would have expected it the be removed (and in fact in the application some business code runs at this time).

For now I can simulate this behaviour by connecting on the editing-started signal and in this callback connecting to the focus-out event of the underlying Gtk.Entry of the Combobox another callback that will emit remove-widget on the original editable.

Some code might make this more understandable (it’s GTK3 because the application is using this version but I could reproduce the behaviour with GTK4):

import gi

gi.require_version("Gtk", "3.0")
from gi.repository import Gtk  # noqa: E402


class TreeViewWindow(Gtk.Window):
    def __init__(self):
        super().__init__(title="Treeview Filter Demo")

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

        self.store = Gtk.ListStore(str, str, float)
        self.store.append(["Yes", "Hello", 12])
        self.store.append(["No", "Goodbye", 2])
        self.store.append(["No", "Brol", 1])
        self.store.append(["Yes", "Foo", 120])

        self.prop_store = Gtk.ListStore(str)
        self.prop_store.append(['Yes'])
        self.prop_store.append(['No'])
        self.prop_store.append(['N/A'])

        self.tree = Gtk.TreeView(model=self.store)

        renderer_1 = Gtk.CellRendererCombo()
        renderer_1.set_property('editable', True)
        renderer_1.set_property('model', self.prop_store)
        renderer_1.set_property('text-column', 0)
        renderer_1.set_property('has-entry', True)
        renderer_1.connect('editing-started', self.editing_started)
        col_1 = Gtk.TreeViewColumn("Propagate", renderer_1, text=0)
        self.tree.append_column(col_1)

        renderer_2 = Gtk.CellRendererText()
        renderer_2.set_property('editable', True)
        col_2 = Gtk.TreeViewColumn("Name", renderer_2, text=1)
        self.tree.append_column(col_2)

        renderer_3 = Gtk.CellRendererText()
        col_3 = Gtk.TreeViewColumn("Weight", renderer_3, text=2)
        self.tree.append_column(col_3)

        self.scrollable_treelist = Gtk.ScrolledWindow()
        self.scrollable_treelist.set_vexpand(True)
        self.scrollable_treelist.add(self.tree)
        self.grid.attach(self.scrollable_treelist, 0, 0, 8, 10)

        label = Gtk.Label(label="Test")
        self.grid.attach(label, 0, 10, 1, 1)
        checkbutton = Gtk.CheckButton()
        checkbutton.connect('toggled', self.button_checked)
        self.grid.attach(checkbutton, 1, 10, 1, 1)

        entry = Gtk.Entry()
        self.grid.attach(entry, 2, 10, 2, 1)

        self.show_all()

    def button_checked(self, button):
        self.prop_store.clear()
        if button.props.active:
            self.prop_store.append(['Foo'])
            self.prop_store.append(['Bar'])
            self.prop_store.append(['Baz'])
        else:
            self.prop_store.append(['Yes'])
            self.prop_store.append(['No'])
            self.prop_store.append(['N/A'])

    def editing_started(self, cell, editable, path):
        entry = editable.get_child()
        entry.connect('focus-out-event', self.focus_out, editable)

    def focus_out(self, entry, event, editable):
        editable.emit('editing-done')
        editable.emit('remove-widget')


win = TreeViewWindow()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()

Is this the expected behaviour of the CellRendererCombo? If so, is my assumption valid that I have to add those two callbacks in order to get the behaviour I expect? If not what would be the canonical way to solve this?

Another issue I have with my solution is that I noticed that it does not work when using X11. It works as I expect it to work under Wayland and Windows but not under X11. Is this an issue worth reporting to the bug tracker?

Thank you for any pointer on how to solve this the GTK way :slight_smile:

it does not work when using X11

In what way does it not work? What happens that is different?

On Wayland, when the edition starts the combobox with its entry appears. When I click on the button to show the options then a popdown appears with the option.

On X11, when the edition starts the combobox with its entry appears. When I click on the button to show the options, the focus-out-event of the entry is emitted, which triggers the focus_out method callback which emits the editing-done and remove-widget signals, which stops the edition. From the user perspective there is no popdown and clicking on the button stopped the edition.

For me this is the main issue, the Gtk.CellRendererCombo does not behave like the other cell renderers which stops the edition when the cursor leaves the cell.

For me it looks like Gtk.CellRendererCombo is missing the same change as cancel editing (ie. don't accept changes) when the entry loses focus. (1cd7347a) · Commits · GNOME / gtk · GitLab

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.