1

i am writing an app with quickly-pygtk-glade and i want to show a dialog and get the return id...I used the run() method but if a close the dialog and reopen it i get an empty window and some errors! I was using destroy() to close it..

Then i tried to use show() method, but i can get a return value from using

id = dialog.show()

how can i get the return id?

Also, how can i get the text from some Entry in the dialog from the main code?

3 Answers 3

3

I found this stackoverflow post, which leads to the documentation on the run function of a GtkDialog, where it states:

The run() method blocks in a recursive main loop until the dialog either emits the "response" signal, or is destroyed. If the dialog is destroyed, the run() method returns gtk.RESPONSE_NONE; otherwise, it returns the response ID from the "response" signal emission. Before entering the recursive main loop, the run() method calls the gtk.Widget.show() on the dialog for you. Note that you still need to show any children of the dialog yourself.

During the run() method, the default behavior of "delete_event" is disabled; if the dialog receives a "delete_event", it will not be destroyed as windows usually are, and the run() method will return gtk.RESPONSE_DELETE_EVENT. Also, during the run() method the dialog will be modal. You can force the run() method to return at any time by calling response() to emit the "response" signal. Destroying the dialog during the run() method is a very bad idea, because your post-run code won't know whether the dialog was destroyed or not.

After the run() method returns, you are responsible for hiding or destroying the dialog as needed.

And also from the PyGTK 3 tutorial:

Finally, there are two ways to remove a dialog. The Gtk.Widget.hide() method removes the dialog from view, however keeps it stored in memory. This is useful to prevent having to construct the dialog again if it needs to be accessed at a later time. Alternatively, the Gtk.Widget.destroy() method can be used to delete the dialog from memory once it is no longer needed. It should be noted that if the dialog needs to be accessed after it has been destroyed, it will need to be constructed again otherwise the dialog window will be empty.

So following on from those bits of information, if you call the hide function of the dialog before it receives the delete event, it will not be destroyed and you can keep calling run, to bring the dialog to focus.

e.g.

def on_mnu_test_dialog_activate(self, widget, data=None):
    result = self.TestDialog.run()
    if result == Gtk.ResponseType.OK:
        print "The OK button was clicked"
    self.TestDialog.hide()

Also, just to answer your second question.

In my example I have imported the class for the dialog:

from dialog_show.TestDialog import TestDialog

Then in the finish_initializing function, I created an instance variable for the dialog:

self.TestDialog = TestDialog()

I can then access a properties like so:

self.TestDialog.ui.txt_entry1.get_text()

or, as suggested by John,

self.TestDialog.builder.get_object("txt_entry1").get_text()
2
  • in my code i have responese = self.ChangePasswordDialog.run() and in the ChangePasswrodDialog.py i use the hide(), but when i open, close and try to reopen the ChangePasswordDialog i get an pretty small empty window...do you want a screenshot?
    – Clepto
    Aug 2, 2012 at 15:50
  • I've seen what you mean about the small empty window. In your code where you run the dialog, directly after, call the hide: result = self.ChangePasswordDialog.run(); self.ChangePasswordDialog.hide()
    – trent
    Aug 2, 2012 at 22:39
1

The project I work on figures out the ui filename and rebuilds the dialog box every time. It shows it and finishes by calling gtk.main().

Various controls are given names in glade-gtk2 and glade-gtk2 is also used to define the cancel and ok buttons. Handlers are named in glade for the signals when these buttons are pressed.

In the code names are also connected to the various controls. For example:

self.use_vertical_layout = builder.get_object('vertical_layout')

The code defines definitions for the handlers and these handlers are connected with builder.connect_signals before the dialog box is shown.

When the handler for ok is called, it can check for the values of the various checkbox controls. In the above case self.use_vertical_layout to represent the value of the checkbox when OK was selected.

Please bear in mind that pygtk is the gtk-2 way of doing things and current versions of quickly use gtk3 and introspection instead (but using a very similar approach).

1
from gi.repository import Gtk

builder = Gtk.Builder()
#correct the path to ui file
builder.add_from_file("ui/stuff.glade")

class Worker:
    def __init__(self):
        self.dia = builder.get_object("MyDialogue")
        self.win = builder.get_object("MyWindow")
    def change_application_settings(self, *args, **kwds):
        '''
        get dialogue states
        '''
        pass
    def reset_dialogue_settings(self, *args, **kwds):
        '''
        set dialogue states
        '''
        pass

worker = Worker()

class Handler:
    def on_mywindow_delete_event(self, *args, **kwds):
        Gtk.main_quit()

    def on_show_dialogue_button_clicked(self, *args, **kwds):
        retval = worker.dia.run()
        worker.dia.hide()
        if retval in [Gtk.ResponseType.OK,
                      Gtk.ResponseType.APPLY, 
                      Gtk.ResponseType.ACCEPT]:
            worker.change_application_settings()
        else:
            worker.reset_dialogue_settings()

builder.connect_signals(Handler())
worker.win.show_all()
Gtk.main()  

I didn't test it, but it's about how it should look.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .