5

I would like to build a GUI for an OCaml application I'm writing. My first idea was to use GTK+. I would like my application to run on Macs, Linux, Windows with a natural look and feel. I know that, while GTK+ uses X11 on the Mac by default (which looks awful), there is gtk-osx-application which uses quartz and looks natural and which I've just installed using macports.

I have three questions:

(1) Is it actually possible to use gtk-osx-application +quartz+no_x11 with OCaml? (My GODI installation which previously (with x11-based gtk2 in place) installed lablgtk2 with no problems, now (with gtk-osx-application +quartz+no_x11 and the previous x11-based gtk2 removed) is complaining about not finding /opt/local/lib/libgtk-x11-2.0.0.dylib, which is x11 related. But, as far as I know, there's no way to choose quartz over x11 when installing lablgtk2 through GODI.)

(2) If I develop my code on my Mac using the gtk-osx-application, can I use the code as is for compilation in other platforms which use different GTKs or can this bring problems?

(3) If it does bring problems, do you know of any other environment for developing GUIs in OCaml that may potentially be good regarding both look and feel and still be readily cross-used? (I am aware of labltk but I'd prefer something with more capabilities, for example, the ability to use notebooks, a.k.a tabbed panels, and being able to use Glade for rapid GUI design.)

Thanks for any help!

Cheers, Surikator

Surikator
  • 1,463
  • 9
  • 26
  • I haven't had to mess with my applications GUI much, but we use REAL BASIC for our x-platform solution. I think it looks pretty damn good. – nlucaroni Jan 28 '11 at 16:14
  • Unless I misunderstood, the cheapest version costs $100. Is this the one you're talking about? – Surikator Jan 28 '11 at 16:34

1 Answers1

3

Assuming you can get lablgtk to work, it is probably your best bet at present.

To get it working: have you tried rebuilding lablgtk after removing X11 GTK and installing Quartz GTK? A LablGTK built against X11 GTK naturally won't work on a Quartz GTK, as it will be linked against the wrong library, but a rebuild might be successful. It could also be that LablGTK won't correctly detect that X11 integration calls don't work and therefore fail to build, but I would expect that to be not-too-difficult to fix as LablGTK does support Windows.

If you develop code for GTK on Mac, it should work on other platforms just fine. You'll want to test it, of course, but it should work. Do be careful to use the GTK facilities to make things like dialog button order work properly.

I think there was at one time a set of OCaml bindings to wxWidgets, but they do not seem to be widely used and wx is painful to work with in my experience. There has also been some work on making Qt bindings, which would be awesome, but I don't think there are any projects with good headway on that front yet.

If the UI is a small-ish piece of your project, you could look at decoupling it from the backend and writing the UI in C++ with Qt, or writing platform-native UIs, and having the UI call out to OCaml code in an embedded runtime to get the real work done. But that is likely more work and may not give you much benefit, depending on your application.

So: GTK is your best option in the current landscape.

Michael Ekstrand
  • 28,379
  • 9
  • 61
  • 93
  • @MichaelE Thanks for the thorough and very useful answer. Glad to hear it works cross-platform.Yes, I considered the backend option, especially because my system will have a terminal/console UI too, so it would seem a viable option. But the GUI should also present some internal ocaml data structures to the users and I wouldn't want to have to replicate them in C++ or something else. So, for now, I'll keep trying to fix my lablgtk2 installation. See my next comment. – Surikator Jan 28 '11 at 18:21
  • @MichaelE Yes, the order was: (1) remove x11 GTK, (2) install quartz GTK, (3) uninstall lablgtk2 in GODI, (4) install lablgtk2 in GODI. I've now managed to install godi-lablgtk2 with the --without-glade and it successfully compiled. That's somehow good news, but one of the great things I was expecting from GTK was precisely Glade. Any ideas? – Surikator Jan 28 '11 at 18:24
  • Also, there's a strange thing happening. If I compile a `helloworld.ml` with `ocamlc -I +lablgtk2 -o helloworld lablgtk.cma gtkInit.cmo helloworld.ml` everything is fine and the executable runs. But if I compile with `ocamlbuild -libs lablgtk -cflags -I,/Users/surikator/godi/lib/ocaml/pkg-lib/lablgtk2 -lflags -I,/Users/surikator/godi/lib/ocaml/pkg-lib/lablgtk2 tmp/toolbar.native` compilation is fine but at runtime I get segmentation fault with lots of things like `GLib-GObject-CRITICAL **: g_signal_connect_data: assertion 'G_TYPE_CHECK_INSTANCE (instance)' failed`. – Surikator Jan 28 '11 at 18:24
  • 1
    @Surikator It looks like you're missing the gtkInit.cmo in the second line. It is necessary to initialize GTK. However, I recommend using ocamlfind to manage libraries and dependencies - it's the standard OCaml solution and takes care of many things for you. Look at the OCamlBuild wiki or `build/myocamlbuild.ml` in Batteries for info on getting ocamlfind and OCamlBuild working together. – Michael Ekstrand Jan 29 '11 at 02:40
  • 2
    Regarding "It could also be that LablGTK won't correctly detect that X11 integration calls don't work and therefore fail to build", it used to be the case more than one year ago, but it has long been fixed. – Pascal Cuoq Jan 29 '11 at 12:01
  • @MichaelE I noticed the missing `gtkInit`. In the ocamlbuild case it should actually be `gtkInit.cmx` (and not .cmo) since I'm compiling for a native executable (toolbar.native). I've read the ocamlbuild manual but I don't really know how to add this for ocamlbuild. The file `gtkInit.cmx` is actually in the (already added directory) `.../godi/lib/ocaml/pkg-lib/lablgtk2` so I would expect ocamlbuild to know where it is. Do you know how I should write the command to add the `gtkInit` information? (For now forget about the myocamlbuild thing, I'll go back to that later.) – Surikator Feb 12 '11 at 21:11
  • @Surkiator Use `ocamlfind`. Under GODI, linking a lablgtk application under ocamlfind automatically adds gtkInit: `ocamlfind ocamlc -package lablgtk -linkpkg -o helloworld helloworld.ml`. On Ubuntu, you need to use the `lablgtk.init` package to get `gtkInit`. – Michael Ekstrand Feb 12 '11 at 22:48