GUI Wizard: flow control?

David Chan david at NOSPAMclocksoft.com
Tue Aug 31 15:38:49 CEST 2004


Hi,

I'm trying to use python to create GUI wizards, i.e. sequences of dialog
boxes with <BACK and NEXT> buttons.  Since I want to re-use some of the
dialog boxes in different wizards, I want to have a main function which
calls each dialog box, much like this:

    def select_item():
        """runs GUI wizard to select item"""

        client = show_client_dialog()
        job = show_job_dialog(client)
        invoice, rate = show_invoice_dialog(job)
        item = choose_item_dialog(invoice, rate)
        return item

This works fine until you want to implement the <BACK button, which should
return to the previous dialog.  Theoretically, what I'd really like is to be
able to jump backwards through the control flow, like this:

    class GoBack(Exception): pass
    def select_item():
        """runs GUI wizard to select item - can go <BACK"""
        back = HERE
        client = show_client_dialog()

        try: job = show_job_dialog(client)
        except GoBack: back.goto()
        back = HERE

        try: invoice, rate = show_invoice_dialog(job)
        except GoBack: back.goto()
        back = HERE

        try: item = show_item_dialog(invoice, rate)
        except GoBack: back.goto()

        return item

But I couldn't find a way of doing anything like that.  You could do
something almost as unhorrible with nested breaks:'

    class GoBack(Exception): pass
    def select_item():
        """runs GUI wizard to select item - can go <BACK"""
        CLIENT: while 1:
            client = show_client_dialog()
            
            JOB: while 1:
                try: job = show_job_dialog(client)
                except GoBack: continue CLIENT

                INVOICE: while 1:
                    try: invoice, rate = show_invoice_dialog(job)
                    except GoBack: continue JOB
                    
                    try: item = show_item_dialog(invoice, rate)
                    except GoBack: continue INVOICE
                    break CLIENT

Or you could do all the flow control manually in a "do_wizard" function and
make the caller create a horrible data structure instead of writing readable
code:

    calls = [
        {'meth': show_client_dialog, 'args': [], 'ret': ['client']},
        {'meth': show_job_dialog, 'args': ['client'], 'ret': ['job']},
        {'meth': show_invoice_dialog, 'args': ['job'], 'ret': ['invoice', 'rate']},
        {'meth': show_item_dialog, 'args': ['invoice', 'rate'], 'ret': ['item']},
    ] # this just says: "client = show_client_dialog()", etc.
    do_wizard(calls, locals())


But this is too hideous to deploy, because I might have to remember what it
does in six months :-)  

Can anyone suggest something better, or should I abandon my goal of having a
main function which calls each dialog box?

Many thanks,
-- 
David Chan
Clockwork Software Systems

intY has scanned this email for all known viruses (www.inty.com)




More information about the Python-list mailing list