How Do I Return Form Data from a Child Window (Dialog) to Parent Window?

I’m sure my problem is not unique and has been asked before. But in order to look for a possible answer one must know the question(s) to ask or the keywords. I have tried: Input Dialogue, Form dialogue, used window rather than dialogue, dialogue rather than dialogue. Therefore please allow me to describe the application and issue.

I have a people logging application. I want to add details of people to the app (name, age, birthday, phone number) sounds familiar? The main window has a short-from list of the people added. The people data is handled by a dataclass which also saves it to a json file. This is handled via the main window.

On the main window is an add button which pops up a window (a Dialog or Window). New person data can be filled in and a save button returns to the main window.

NOW MY PEOBLEM: I need to get the new data back to the parent, ‘main’, window control so it can update the people dataclass, the json file and then the main window short-from list. But how?

I did consider directly accessing the people dataclass but the main window control is already controlling it. I foresaw dragons on that route.

I haven’t explicitly mentioned but I’m using Python and Gtk3. I would really prefer not to share my code at this point.

Any advice, pointers keywords, a previous solution would be appreciated.

Regards Greg

Idea/suggestion: The parent window could subscribe to a custom signal that the dialogue emits when form data is submitted. The signal’s payload can be any object, e.g., representing the form data or the person that was edited.

Further reference, pygobject docs about signals:
https://pygobject.readthedocs.io/en/latest/guide/api/signals.html

(I am unsure if this answer fits your architecture, and I don’t know how you would combine this with dataclasses, but I thought I’d still post this, hoping you find it helpful).

Best regards, Johannes

Thanks for responding.

As is often the way one trips over a solution on stackoverflow when looking for something else. I have appended my version below should it help others.

The only part of the solution I didn’t follow was the use of ‘lambda’ function in the connect function. Perhaps your reference to signals may provide enlightenment. Thanks

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk


class EntryDialog(Gtk.MessageDialog):
    def __init__(self, *args, **kwargs):
        """
        Inherits from MessageDialog (also works for Dialog), however
        the run() method overridden.

        EntryDialog constructor accepts one optional argument "default_value"
        to specify the initial contents of the entry field.

        Note the rather odd button connect to callbacks.

        This example is strongly based upon the following:
        https://stackoverflow.com/questions/8290740/simple-versatile-and-re-usable-entry-dialog-sometimes-referred-to-as-input-dia
        """
        if 'default_value' in kwargs:
            default_value = kwargs['default_value']
            del kwargs['default_value']
        else:
            default_value = ''
        super().__init__(**kwargs)

        entry = Gtk.Entry()
        entry.set_text(str(default_value))
        self.vbox.pack_end(entry, True, True, 0)

        close_btn = Gtk.Button()
        close_btn.set_label("Close")
        # close_btn.connect("clicked", self.close_btn_btn_clicked)  # Not usable in this context
        close_btn.connect('clicked', lambda _: self.response(Gtk.ResponseType.CLOSE))
        self.vbox.pack_start(close_btn, True, True, 0)

        save_btn = Gtk.Button()
        save_btn.set_label("Save")
        # save_btn.connect("clicked", self.save_btn_clicked)  # Not usable in this context
        save_btn.connect('clicked', lambda _: self.response(Gtk.ResponseType.OK))
        self.vbox.pack_start(save_btn, True, True, 0)

        self.vbox.show_all()
        self.entry = entry

    def set_value(self, text):
        self.entry.set_text(text)

    def close_btn_clicked(self, button):
        pass

    def save_btn_clicked(self, button):
        pass

    def run(self):
        result = super(EntryDialog, self).run()
        text = self.entry.get_text()
        if result != Gtk.ResponseType.OK or (text == ''):
            text = None
        return text


class DialogLaunchWin(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Dialog Example")

        self.set_border_width(6)

        button = Gtk.Button(label="Open dialog")
        button.connect("clicked", self.on_button_clicked)

        self.add(button)

    def on_button_clicked(self, widget):
        dialogue = EntryDialog()
        dialogue.set_value("Field Initial Value")  # Optional
        response = dialogue.run()
        print("DEBUG: Dialogue exists with response: ", response)
        dialogue.destroy()


def main():
    win = DialogLaunchWin()
    win.connect("destroy", Gtk.main_quit)
    win.show_all()
    Gtk.main()


if __name__ == "__main__":
    main()

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