tags:

views:

1226

answers:

11

I've been working on a project of porting an old solaris CL program to run on Linux, and barring some unrelated hardware issues, that's finished. Now I want a GUI for it, so the user can choose among the various options with drop downs and check boxes, as well as some text input areas for options that aren't so restricted, like the filename. (The program is an internal tool to run some spectroscanners and store the results as CSV files. It handles all these options, runs the scanners and processes the info and stores it with the specified filename; I just want something nicer to use than CL.)

The only time I've seen something like this done was a PyGTK+ GUI with python bindings for the C code (I think that's what it was; that was my first semester co-opping and I didn't understand very much!). That's a bit more than I want to get into right now; is there a relatively easy way to do this? When I Googled I found SWIG (http://www.swig.org/index.php); is this a good way to go?

+1  A: 

Since you are already familiar with PyGTK, why not use Gtk+? After all, PyGTK are just bindings round Gtk+, which is written in C.

Its cross-platform, too. So if you use GLib your application will run almost anywhere.

Mark A. Nicolosi
I don't know about familiar...I added some functionality to the existing project, which had been written by a couple guys who started programming before they were out of diapers...
kajaco
Oh, well, in that case... I still highly recommend it. ;)
Mark A. Nicolosi
+3  A: 

I've used tcl/tk to wrap smaller CLI programs before and it often works fine to start with.

tcl/tk is a script language/package that will be calling and parsing the CLI output so you don't have to write a new program

tcl/tk

epatel
"to start with" sounds ominous for later on!
kajaco
well, yeah...often there is a request for a "full" program, but to start with a tcl/tk often is enough. If it's done good enough it might stay there :)
epatel
"to start with " *is* ominous for later on. I"m very glad I no longer have to maintain any of my old Tcl/Tk code!
Norman Ramsey
+15  A: 

This sounds like exactly the job Tcl/Tk was designed for. It has a very simple C API that allows you to register commands with a callback. If you use the command in a Tcl program, it will invoke the callback and provide a mechanism to convert the arguments between a Tcl list (native data structure) and an ARGV style array of char*.

It was designed specifically to be easy to retrofit this sort of wrapper to command-line driven C programs. There are also a variety of other modes you can use to interface the interpreter as well, and it is easy to embed into programs as a scripting language. From memory the available interfacing mechanisms are:

  • Register commands in the Tcl interpreter
  • Embed a Tcl interpreter in your program and use Tcl as an embedded scripting language (possibly including registration of commands and callbacks to your program)
  • Spawn a process with a full-duplex pipe and send commands via stdin/stdout (you can also attach an event handler to the pipe which is invoked when data is available)
  • Less Tcl specific mechanisms such as fork/exec or connection via sockets.

Ousterhout's book Tcl and the TK Toolkit is a bit dated but has a good guide to the C API. Welch's Practical Programming in Tcl/Tk is the other classic Tcl/Tk book and is updated more frequently. There are also several other books and quite a lot of electronic resources on the internet. Some good starting points are: Tcl tutorial, TK tutorial, Tcl advocacy site (might be worth perusing to help you decide if you want to go down this route), Tcl/Tk Wiki and of course Stackoverflow.

TK will give you a straightforward GUI and is very easy to learn to program - if a little simplistic. It's not as ugly as it used to be if you take some time to tweak the appearance or use a theming engine such as Tile.

As Norman Ramsey points out (+1), another alternative with a simple C API is Lua. Both have advantages and disadvantages. The principal strengths of Tcl are the simple and cleanly integrated TK toolkit and good, mature support support from third party libraries (e.g. Tix). The main strength of Lua is that the language is much nicer but there is no standard GUI toolkit, so the UI is not as nicely integrated. Lua also has much better support for threading in the interpreter, having been designed for this from the ground up. However, if you're wrapping a legacy C/unix application, this is unlikely to be a significant feature.

WXWidgets is considerably more complex than TK and carries more runtime baggage but has a richer feature set.

If you have genuine reason to think that your scripting project will grow into a larger application you might consider Lua. However at a larger scale you're into a substantial development project and Python or Ruby start becoming viable options. As the project gets larger wrapping the C codebase will be a smaller portion of the overall project and third-party library support will be a bigger consideration.

If you go with Tcl and discover your project gets a life of its own, consider embedding the Tcl interpreter and re-casting the application as a plugin API that people can hook their own scripts into. Extra features can be done as scripts and possibly fobbed off onto third parties for maintenance. One of the advantages of a system with a built-in scripting language is that you personally do not necessarily have to implement features. People can write their own extensions in the scripting language or get third parties to do it for them.

SWIG is designed to generate wrappers around libraries. It parses the header files and generates a glue layer that presents a native API in the target language. To use it, you would have to re-factor your program into a library.

ConcernedOfTunbridgeWells
A few more edits and this will go wiki. Anyone wanting to write a Lua advocacy piece with a bit more depth (I'm much more familiar with Tcl than Lua) can you add a reply and not it in the comments here. I'll add a link from this.
ConcernedOfTunbridgeWells
Forget Oosterhout's book, the Brent Welch book is THE standard work nowadays on Tcl/Tk.
Roalt
+3  A: 

How about Tcl/Tk .. plenty of resources .. such as this

Scott Evernden
A: 

Any toolkit or framework can solve your problem since you're requesting an UI which acts as a wrapper for your command-line executable. You may choose C#, MFC, VB6, any tool you want. The .NET-based languages such as C# are quite easy for command line UI wrappers. wxWidgets, Qt or Ultimate++ can help you if you want to do it in C++.

If you know how to program in C, you can do it in plain Win32 API, altough you must manage some things that are handled automatically in the C++ frameworks.

Hernán
This is to run on an Ubuntu box; will your suggestions work?
kajaco
All right, for Linux you've Qt (for GPL, you must pay for commercial ), GTK+ (Anjuta, great IDE for it) or Ultimate++ (C++ multiplatform). Another option in the C++ field is WxWidgets. . This is a very mature framework, it's completely free (even if you are planning selling your app).
Hernán
A: 

I think MGUI is a thing you can go with!

MGui (MORELLO Graphic User Interface) is a cross-platform graphical user interface written in ANSI C, also providing a C++ API via a frame library. It consists of a library, including all typical GUI objects as menu, push buttons, editable fields, lists etc... and a code generation tool (MGui Designer), which allows the user to create and maintain application window layouts using the mouse.

MGui makes it possible to create applications for Windows 3.1, Windows 95/98/NT, Unix X-Window, DOS (Borland, Watcom and DJGPP) with no knowledge about the host system graphics API. You can simply use the MGui Designer code generator to create window layouts, and write your code to interact with the created Objects.

For its features, MGui is useful to everyone who wants to realize multi platform applications, with absolutely no GUI porting needs. It's ideal for use in DOS based embedded systems in both real mode and DPMI.

By the way here is a very good list of libs.

joki
A: 

You can use any toolkit you like (tcl/tk or any other scripting language you are comfortable with that has a GUI capability), but the advice to keep the original as a CLI program (which your GUI then runs after collecting options from the user) is good. No need to get into C bindings etc.

frankodwyer
A: 

If you need text-mode UI in your program, TxWin is a good option.

Another one,TVision a clone of the gool ol' Borland TurboVision.

Hernán
+3  A: 

I have to second Tcl/Tk. I did exactly the same thing for legacy programs written in Fortran/C/C++. Since it's very trivial to write a DSL in Tcl/Tk, I ended up just adding an option for the program to output DSL (essentially Tcl commands written in procs) for tk program to eval. I've done this for a program with to do fairly complex graph animations on a tk canvas, that has options to save portion of the animation in mpeg in about 4 hours. People were amazed. It's completely portable as well. Tcl/Tk has simple, yet sophisticated event driven facilities (that's still unparalleled in its simplicity) to write GUI apps. You can use simple pipe to interface with legacy programs as long as it can read from standard input and write to standard output.

The huge advantage of this approach is that you don't need to link any GUI or additional libraries with your legacy programs, which is sometime impossible. The GUI and legacy program can be completely decoupled.

And that's about 10 years ago. Tk has evolved/improved a lot since then and gained native look and feel capability.

The major disadvantage used to be packaging standard-alone Tcl/Tk programs, which is largely solved now as well.

EDIT: DSL stands for 'Domain Specific Language' Extensions to the Tcl interpreter manifest themselves as new language keywords. Tcl has a fairly basic syntax, so this mechanism allows quite a lot of scope for extending the language. A good example of an application that does this with Tcl is Expect.

obecalp
+4  A: 

As others have said, Tcl/Tk is a good choice. There is a real risk you will outgrow the Tcl language, but that risk is mitigated by the excellent power and simplicity of the Tk windowing toolkit.

The other choice I would consider is wxlua. The reasons are that Lua is a language you will not outgrow. You might also prefer wxlua because it is based on wxwidgets, which will give you GUI a native look and feel. The original Tk had a rather strange and very non-native look and feel, but things are much better now, so this reason may not carry much force. You might look over the two GUI toolkits to see what appeals. A final reason you might prefer Lua is that it is easier to expose user-defined data types to the GUI and to scripts.

I would not consider alternatives such as Python and Gtk+, because of all the alternatives out there, only Tcl and Lua were designed from the start to be married to C programs.

You also ask about SWIG. Although it is superficially attractive, I recommend avoiding it. Both Tcl and Lua have very simple C APIs and you will learn more, understand better, and be in better control of your application if you learn to use the native API yourself instead of having SWIG generate code for you.

Norman Ramsey
Could you elaborate on what you mean by "outgrow" a language?
kajaco
Tcl is fairly clumsy for writing large applications in - it's not really designed for highly structured programs manipulating complex data structures. Lua is better for this, but the GUI toolkit options aren't as well integrated or easy to use.
ConcernedOfTunbridgeWells
@kajaco: One day you have a nice sensible 200-line application. Two months later you have 2000 lines of unmaintainable mess, which your language has little or no support for refactoring. (It has happened to me all too often.)
Norman Ramsey
@NXC: violently agree. Original Tcl had no data structures; *everything* was strings. Retrofitted hash tables pinch like an ill-fitting shoe. But the Tk toolkit is a wonder: simplexst and easiest I've used in *any* language.
Norman Ramsey
@Norman: If you've used Lua a lot do you want to add a little advocacy piece here and cross link between it and my blurb on Tcl.
ConcernedOfTunbridgeWells
@NXC: I've used *both* Lua and Tcl a lot, and for some GUIs Tk really is the best thing I've ever seen. If you're going to knock out a small thing fast, Tcl/Tk is very tempting. If it then grows into a monster, you'll be sorry. But there's no *GUI* toolkit for which I can honestly advocate Lua.
Norman Ramsey
Programming Tcl/Tk with large applications requires discipline. Split your code in packages and separate files, use namespaces. I've written 20000+ lines of code applications in Tcl/Tk and never lost the overview.
Roalt
@Roalt, @Norman: Also - as I've noted in my post above - as the program gets larger the overhead of interfacing gets proportionally less, so Python or possibly Ruby become more attractive.
ConcernedOfTunbridgeWells
@Roalt: Agree - with discipline you can use Tcl for large programs. At one point I was involved in a 350,000 LOC VB6 project that we managed to keep on the straight and narrow.
ConcernedOfTunbridgeWells
Programming large applications with ANY language requires discipline. You can write crap-tastic programs in Lua just as easily as with Tcl
George Jempty
@George: yes, a bad programmer can write crappy code in any language. Probably equally easily. But in Tcl, you have to work **really hard** to keep a big application maintainable. In Lua, you don't.
Norman Ramsey
Honestly, I've always found Tcl to be amazingly easy to write larger applications in, with complex data... and I find Lua to be extremely annoying to work with when doing anything even moderately complicated. Everything is a table may work for some folks, but I find it (and the nuances of Lua layered on top of it) to be very hard to manage.
RHSeeger
A: 

Without getting into recommending specific libraries or GUI toolkits, do be aware that most GUIs work on an "event driven" model.

That means that most of the time the application is doing something like this:

  1. wait for an event (e.g. keyboard input, timer expiry, etc)
  2. call some user-specified function based on that event
  3. loop back to step 1.

If the function that is called takes a significant amount of time it makes your program unresponsive.

Working around that means either having your GUI handled in another thread, or the ability for long-lived functions to occasionally yield to check whether the user has tried to abort them.

Alnitak