Subclassing Adw.EntryRow

G’day!

I’m subclassing Adw.EntryRow and would like to prevent it from emitting the apply signal if it is invalid. I’ve played around with self.stop_emission_by_name("apply") but that just makes things weird.

Any help is most appreciated.

A workaround would be to handle the object’s own apply signal and emit an apply-valid signal conditional on the validation, but I’m still curious as to how I’d suppress apply itself conditionally.

Also, I’m using Gtk.Template and Gtk.Template.Callback in Python if that’s relevant.

Hi,

From what I see, it doesn’t seem something straightforward to do.
That would help if apply was a virtual method, but sadly it’s not the case.

Either go for your workaround, or monitor the entry’s content and hide the apply button when the conditions are not fulfilled.

I’ve gone with the workaround. Here it is:

@Gtk.Template(resource_path="/org/bswa/Leaftracker/ui/validated_entry_row.ui")
class ValidatedEntryRow(Adw.EntryRow):
    __gtype_name__ = "ValidatedEntryRow"

    def __init__(self):
        super().__init__()
        self._validate_entry: Callable[[str], bool] = lambda entry: True

    def entry_is_valid(self) -> bool:
        text = self.get_text()
        return self._validate_entry(text)

    def clear(self):
        self.set_text("")
        self.set_show_apply_button(False)
        self.set_show_apply_button(True)

    def set_validator(self, validator: Callable[[str], bool]):
        self._validate_entry = validator

    @Gtk.Template.Callback()
    def _on_changed(self, instance: Self) -> None:
        text = self.get_text()
        valid = self._validate_entry(text)
        self.set_show_apply_button(valid)

    @Gtk.Template.Callback()
    def _on_apply(self, instance: Self) -> None:
        if self.entry_is_valid():
            self.emit("apply-valid")

    @GObject.Signal
    def apply_valid(self) -> None:
        pass
<?xml version='1.0' encoding='UTF-8'?>
<interface>
    <template class="ValidatedEntryRow" parent="AdwEntryRow">
        <property name="show-apply-button">true</property>
        <signal name="changed" handler="_on_changed"/>
        <signal name="apply" handler="_on_apply"/>
    </template>
</interface>

Note that AFAIK, setting show-apply-button to false does not necessarily stop you applying. You can still hit enter? Haven’t tested so I’m not sure. Extending the control with a new signal seems a better pattern.

1 Like