Jamie Lindsey
Jamie Lindsey

Reputation: 993

How to pass/return data from Gtk dialog to main application class

I have an application in Python Gtk. I have my main Application class in my main file. I then have all my dialogs in a different file. I need to be able to pass/return custom data from the dialog to the main application class other than the standard Gtk response codes, here is some basic example code as my own code is very long:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class DialogWindow(Gtk.Window):

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

        self.set_border_width(6)

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

        self.add(button)

    def on_button_clicked(self, widget):
        dialog = DialogExample(self)
        response = dialog.run()

        if response == Gtk.ResponseType.OK:
            print("The OK button was clicked")
        elif response == Gtk.ResponseType.CANCEL:
            print("The Cancel button was clicked")

        dialog.destroy()

win = DialogWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

The dialog window in a separate file:

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class DialogExample(Gtk.Dialog):

    def __init__(self, parent):
        Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             Gtk.STOCK_OK, Gtk.ResponseType.OK))

        self.set_default_size(150, 100)

        label = Gtk.Label("This is a dialog to display additional information")

        box = self.get_content_area()
        box.add(label)
        self.show_all()

As standard we apply the Gtk.ResponseType to the buttons. But what if we want to return some custom data - not just a simple response code - as a further code example:

class DialogExample(Gtk.Dialog):

    def __init__(self, parent):
        Gtk.Dialog.__init__(self, "My Dialog", parent, 0)

        self.set_default_size(150, 100)

        label = Gtk.Label("This is a dialog to display additional information")

        button = Gtk.Button("Return something")
        button.connect("clicked", self.on_button_clicked)

        box = self.get_content_area()
        box.add(label)
        self.show_all()

    def on_button_clicked(self, widget):
        if SOME_CONDITION:
            return <CUSTOM_RESPONSE>
        else:
            return <ALT_CUSTOM_RESPONSE>

When I do the last example the dialog does not return anything, I would like to do something like:

class DialogWindow(Gtk.Window):

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

        self.set_border_width(6)

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

        self.add(button)

    def on_button_clicked(self, widget):
        dialog = DialogExample(self)
        response = dialog.run()

        if response == <CUSTOM_RESPONSE>:
            #do something with <CUSTOM_RESPONSE>
        elif response == <ALT_CUSTOM_RESPONSE>:
            #do something different with <ALT_CUSTOM_RESPONSE>

        dialog.destroy()

win = DialogWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

The DialogExample window does not destroy/close and nothing is returned and the application basically just pauses as it thinks there are no more methods to run - although there is much to be done after the return of the custom data (I need to then start adding records to a database).

[UPDATE]

I have now tried so many various things to solve this issue I could not possibly list them all here. I have searched endlessly for some kind of answer and it would seem this is not something that is done by anyone on the Internet.

Upvotes: 3

Views: 2064

Answers (1)

AndreLDM
AndreLDM

Reputation: 2198

The C version of gtk_dialog_run is limited to return integers, you can set custom values but nothing like strings or objects. You can workaround this by setting a value on the "response" signal and then get it after the run function returns.

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class DialogExample(Gtk.Dialog):

    def __init__(self, parent):
        Gtk.Dialog.__init__(self, "My Dialog", parent, 0,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
             Gtk.STOCK_OK, Gtk.ResponseType.OK))

        self.result = ""
        self.set_default_size(150, 100)
        self.connect("response", self.on_response)

        label = Gtk.Label(label="Type something")
        self.entry = Gtk.Entry()

        box = self.get_content_area()
        box.add(label)
        box.add(self.entry)
        self.show_all()

    def on_response(self, widget, response_id):
        self.result = self.entry.get_text ()

    def get_result(self):
        return self.result

class DialogWindow(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="Dialog Example")
        self.set_border_width(6)

        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(box)

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

        self.label = Gtk.Label()
        box.add(self.label)

    def on_button_clicked(self, widget):
        dialog = DialogExample(self)
        response = dialog.run()

        if response == Gtk.ResponseType.OK:
            self.label.set_text(dialog.get_result())
            print("The OK button was clicked")
        elif response == Gtk.ResponseType.CANCEL:
            print("The Cancel button was clicked")

        dialog.destroy()

win = DialogWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

Upvotes: 4

Related Questions