Published on 11 February 2012.
In this post I explain how I got started writing code for the file organization application. I describe the first two commits and the thoughts behind them.
Since I was unfamiliar with the technologies that I had chosen, my first goal was to get a hello world program working. If I can get that working, I gain confidence that I can use the technologies together.
In this case, the technologies were Haskell and GTK (with Haskell bindings). I had played with Haskell before but was completely new to GTK (although not to event-driven GUI programming).
I copied a hello world example from the Gtk2Hs website and pasted into a source file. It looked like this:
import Graphics.UI.Gtk
= do
main
initGUI<- windowNew
window <- buttonNew
button := 10, containerChild := button ]
set window [ containerBorderWidth := "Hello World" ]
set button [ buttonLabel putStrLn "Hello World")
onClicked button (
onDestroy window mainQuit
widgetShowAll window mainGUI
Compiling was easy once I had downloaded the required libraries. They were all available through the package management system on my GNU/Linux system. I made a script for compiling so that I wouldn’t have to remember how to do it:
ghc --make Main.hs -o org-app
(The make flag tells ghc
to figure out all dependencies so you only need to specify the top level program you want to compile. When you compile your project multiple times, ghc
will only recompile files that have changed.)
And that was the first commit: a working skeleton on which to build. I could now easily explore features of GTK and GUI programming in Haskell by playing around with the hello world program.
The hello world program constructs the GUI in code by creating widgets and manually placing them on a window:
<- windowNew
window <- buttonNew
button := 10, containerChild := button ]
set window [ containerBorderWidth := "Hello World" ] set button [ buttonLabel
I’ve had experiences designing GUIs like this and it’s quite tedious. It takes a long time to get all parameters right so that your windows look the way you imagined. The code also becomes rather long and messy.
For GTK, there is a tool called Glade which lets you design your widgets visually and then load them from an XML file in code.
I wanted to try this approach. I decided to see if I could transform the hello world example from the first commit using Glade. I came up with this:
import Graphics.UI.Gtk
import Graphics.UI.Gtk.Builder
= do
main
initGUI
<- builderNew
builder "interface.glade"
builderAddFromFile builder
<- builderGetObject builder castToWindow "main_window"
mainWindow
onDestroy mainWindow mainQuit
<- builderGetObject builder castToButton "hello_world_button"
helloWorldButton putStrLn "Hello World")
onClicked helloWorldButton (
widgetShowAll mainWindow mainGUI
Now the widgets are loaded from the XML file interface.glade
and we only have to hook up the event handlers. The text and position of the hello world button is stored in the glade file. Instead of this:
<- windowNew
window <- buttonNew
button := 10, containerChild := button ]
set window [ containerBorderWidth := "Hello World" ] set button [ buttonLabel
We have this:
<- builderGetObject builder castToWindow "main_window"
mainWindow <- builderGetObject builder castToButton "hello_world_button" helloWorldButton
This doesn’t look like less code (it’s actually the exact same number of lines in total), but when the GUI gets more complex, I think this will pay off.
And that was the second commit.
At this point there are no tests or no code specific to the application. But the code proves that these technologies can be used together, and I’ve gained confidence that I can move forward.
What is Rickard working on and thinking about right now?
Every month I write a newsletter about just that. You will get updates about my current projects and thoughts about programming, and also get a chance to hit reply and interact with me. Subscribe to it below.