How can I create a GUI on top of a Python APP so it can do either GUI or CLI?
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, GU开发者_如何学PythonI 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
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.
The actual work:
foo_core.py
.A CLI module that imports
foo_core
. Call itfoo_cli.py
.A GUI module that imports
foo_core
. Call itfoo_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()
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.
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.
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.
精彩评论