2

I'm prototyping GUI layout with PyGTK, sometimes using glade/builder sometimes not, and the following scene repeats endlessly:

  1. Modify the code
  2. Run the GUI script
  3. Judge the result
  4. Modify again
  5. Run again...

So, since I heard that Python allows reloading of modules, I would like to know if it is possible to modify the code WITHOUT CLOSING THE WINDOW, and then, from the window itself, say, clicking on a button, "reload" the window reflecting the changes in code.

Since it is a conceptual question, I don't have any specific code to show.

Thanks for the attention

1 Answer 1

1

I think it is possible if you do the following:

  1. Identify and isolate the widget W that you want to see updated when you press the button (if you want to see the whole window updated, then make it whatever you add in the window, not the window itself).
  2. Write a function (or class) that creates and returns this widget
  3. Put this function or class in a module that you will reload
  4. Create your button outside W and connect it to a function that does the following
    • Remove current W from window
    • Reload the module
    • Create new instance of W
    • Add it to the window

Of course, the critical step here is "reload the module". I guess you have to make sure no code from the module is running and no other module depends on variables defined on this module.

EDIT: I had some time, so I made a little prototype. Change the label in widget_module.py and then hit Update

gui.py

# Load in pygtk and gtk

import pygtk
pygtk.require('2.0')
import gtk
import widget_module

# Define the main window

class Whc:
    def __init__(self):
        # Window and framework
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", self.destroy)

        # A Button, with an action
        # Add it to the geometry
        # show the button
        self.button = gtk.Button("Update")
        self.button.connect("clicked", self.update, None)

        self.vbox = gtk.VBox()
        self.vbox.pack_start(self.button)
        self.widget = widget_module.get_widget()
        self.vbox.pack_start(self.widget)

        self.window.add(self.vbox)


        # Show the window
        self.window.show_all()

    # Callback function for use when the button is pressed

    def update(self, widget, data=None):
        print "Update"
        self.vbox.remove(self.widget)
        reload(widget_module)
        self.widget = widget_module.get_widget()
        self.vbox.pack_start(self.widget)
        self.widget.show()


    # Destroy method causes appliaction to exit
    # when main window closed

    def destroy(self, widget, data=None):
        gtk.main_quit()

    # All PyGTK applicatons need a main method - event loop

    def main(self):
        gtk.main()

if __name__ == "__main__":
    base = Whc()
    base.main()

widget_module.py

import pygtk
import gtk

def get_widget():
    return gtk.Label("hello")
Sign up to request clarification or add additional context in comments.

1 Comment

Great, Jong, your answer was very helpful. I was always thinking on destroying the whole window, but since the widget tree can be always nested inside some "parentmost" widget, the net effect should be the same or even better. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.