[Tutor] Hopefully OT

Martijn Faassen M.Faassen@vet.uu.nl
Wed, 02 Jun 1999 22:29:43 +0200


K P wrote:
> 
> Disclaimer: Begining programmer question!
> 
>         How would a GUi be implemented? This is not a question about which
> GUI/TK library to use (I happen to be using wxPython), but more on, how to
> give a program more than a CLI. Mayeb a quick example with this:
 
[snip]

> Ok, dumb program. My question then would be, if I gave this 'program' a
> gui, how would I write it to use my self-made class? After looking at the
> docs for several GUI/TK libraries, I find myself confused how to accomplish
> this. If anyone has any general GUI faqs/tutorials/etc please let me know.

The basic advice I can give you here is to at all times separate the
program logic from the particular interface code you're using, unless it
is a trivial program. In general, avoid letting program code call the
GUI, try to let the GUI code call the program code instead.

Not mingling program with GUI code gives you:

* Easier to think about and maintain. This is most important; by
disconnecting GUI code from your actual program you can think about the
structure more easily. No spaghetti connections; you don't to delve
through GUI code (which isn't well known for its amazing elegance,
usually) to change the way your program works.

* Enhanced portability; you can keep the core app more portable to
different OSes at least. You can switch to a different GUI in the
future.

* Possibility for a power-user command line interface, or 'batch run'
interface

What you do in some imagined GUI (IGUI) system is this:

import IGUI
import MyReport

class ReportWindow(IGUI.Window):
    def __init__(self, start_report):
        # call the Window base class with some parameters to set things
up
        IGUI.Window.__init__(self, "Title: Report", 200, 200)
   	# add a button to the Window now, called 'Update'. Call
'self.update'
        # whenever this button is pressed
        self.mybutton = self.addButton(" Update ", self.update)
        # also put an text entry box on the window
        self.textentry = self.addTextEntry("Which report?", 
                                           self.setReport,
when=IGUI.OnChange)
        # set some labels for output
        self.labela = self.addLabel()
        self.labelb = self.addLabel()

        # the current report we show when 'Update' is pressed
        self.current_report = start_report

    def update(self):
        # always display the current report
        self.showReport(self.current_report)

    def setReport(self, text):
        # the IGUI system sends a string whenever the text entry changes
        # (if 'when' is set to OnChange)
        
        # try to find a new report object in a ReportDatabase object
that's
        # defined in the main program code
        report = MyReport.ReportDatabase.lookup(reportname = text)
        # ReportDatabase.lookup() returns the report object if a report
object
        # with that name exists, otherwise None
        # if we found a report with that name it is the new current
report
        if report != None:
            self.current_report = report

    def showReport(self, report):
        # report is some actual application object that generates a
report of
        # whatever
        spamtext = report.getSpamInfo()        
        # show it in label a
        labela.setText(spamtext)
        if report.reportIsGood():
            labelb.setText("This report is good!")
        else:
            labelb.setText("Dreadful spam statistics!")

The main idea is that you assemble a GUI window or form by placing some
GUI widgets (like buttons and text and so on) onto it. You connect some
widgets with special methods or objects in your program that catch the
event messages they sent (for instance when a button is pressed). The
output widgets generally are changed by calling special methods in them
(like .setText() for the label, for instance).

Okay, aside from this basic advice I'm no expert on GUI design. It seems
that one of the most elegant structures is the 'model-control-view'
approach, so look that one up.

I hope this helps some, good luck!

Regards,

Martijn