views:

191

answers:

4

Hello,

I am trying to write an app in python to control a motor using serial. This all works in a CLI situation fine and is generally stable. but I was wondering how simple it was to add a GUI on top of this code base?

I assume there will be more code, but is there a simple way of detecting something like GTK, so it only applied the code when GTK was present?

Also, GUI creation in Python in general: is it best to keep as little GUI specifics out of the code and use something like GTK's XML based approach (using gtk.glade.XML() function)? Are there other GUI toolkits that have a similar approach to the Glade / XML / "Explode in Code" approach?

Thanks for any advice.

Andy

+9  A: 

is there a simple way of detecting something like GTK, so it only applied the code when GTK was present?

First, break your app into 3 separate modules.

  1. The actual work: foo_core.py.

  2. A CLI module that imports foo_core. Call it foo_cli.py.

  3. A GUI module that imports foo_core. Call it foo_gui.pyw.

The foo_cli module looks like this.

import foo_core
import optparse

def main():
    # parse the command-line options
    # the real work is done by foo_core

if __name__ == "__main__":
   main()

The foo_gui module can look like this.

 import foo_core
 import gtk # or whatever

 def main()
     # build the GUI
     # real work is done by foo_core under control of the GUI

 if __name__ == "__main__":
     main()

That's generally sufficient. People can be trusted to decide for themselves if they want CLI or GUI.

If you want to confuse people, you can write a foo.py script that does something like the following.

try:
    import foo_gui
    foo_gui.main()
except ImportError:
    import foo_cli
    foo_cli.main()
S.Lott
A: 

I don't recommend doing a GUI in XML. All the XML does is give you a mini language for describing a layout. Why use a mini language when you can have the full power of python?

As for detecting GTK, I wouldn't suggest that. Instead, add a command line argument to determine whether to create a GUI or not (eg: myprogram -g). It then becomes easy to create a desktop shortcut or command line alias to start in GUI mode, while still being able to use the command line tool from any terminal.

You do, however, want to keep the GUI code separate from the bits that do the real work. Give youself a class that contains all the business logic, then have the GUI and CLI both access this object to do work.

Bryan Oakley
+1  A: 

It depends on which kind of interaction you want.

If you want a real GUI you can use the humble dialog pattern to decouple the GUI stuff from the program logic, and use a text "GUI" to handle the CLI. This also has the nice side-effect that big parts of the GUI get programmable testable.

Another way is to assign sys.stdin and sys.stout with own objects, which redirect your programs IO to the GUI (this does not work with non-python libraries). This means that you have fewer interaction possibilities in the GUI, but much less programming effort.

Rudi
+1 good link, thanks
msw
A: 

Well, what I do is that I have a one and only bash script with the following:

if [ "${0}" == "mcm" ]; then
    /usr/bin/python ${inst_dir}/terminal/mcm-terminal.py ${@}
else
    /usr/bin/python ${inst_dir}/gtk/mcm-gtk.py &
fi

Then I create two symlinks: /usr/sbin/mcm and /usr/bin/mcm-gtk

Works very nice.

Ubersoldat