Clojure and QT for desktop applications
Up until now I have exclusively talked about web applications, and to a degree that stems from my mindset that the future of applications is the web. I stand by that…with caveats.
I’m embarking on a new personal project which requires a pure offline environment, something I haven’t done in any form in years and realistically have never done. Even in my past working with C# applications they always connected to remote databases maintained on networks and relied heavily on server storage. So for me, this will be my first time working on a stand alone desktop application.
Of course the Clojure comes in because I want to build something cross platform, targeting Mac OSx and Windows XP – 8…okay maybe not 8. I’m not sure yet.
At any rate if you’re not familiar with QT you should be. It’s a cross-platform UI framework maintained/developed by Nokia available through an LGPL license, making it a legitimate choice for commercial and open source uses.
Getting everything installed:
Now because Clojure is a JVM based language you can count on using the Java libraries to hook QT into Clojure. Let’s go ahead and assume that you’ve installed Clojure 1.4.0 through HomeBrew, because that’s what I did.
Now you’re going to want to download the QT Jambi library, this is the java implementation of QT. Simply unzip the package
To run the sample binary to view some of what QT Jambi can do simply terminal to your new qt jambi folder and run the following commands.
chmod +x qtjambi.sh
Note: You may need to open qtjambi.sh and add ”-d32″ to the java command being called near the end of the file, this will force it to run in 32-bit mode, which is required for Lion/Mountain Lion
Now what I did was install qtjambi into my local maven repository using the following command:
mvn install:install-file -Dfile=qtjambi-4.7.0.jar -DartifactId=qtjambi -Dversion=4.7.0 -DgroupId=qtjambi -Dpackaging=jar
But there are other ways to get your dependencies loaded, I just have a preference for my local maven repo.
Writing your hello world:
So, of course, we’re going to do the old stand-by HelloWorld app.
The first thing we’re going to do is create a new project in lein by doing a simple lein new hello_world.
Add :main hello_world.core to your project.clj in your new application.
Go ahead and define main in your core.clj file, it should look something like this:
(defn -main  (println “Hello World”))
Now on to the GUI!
We didn’t come here to print stinkin’ lines! Still, if everything runs with lein run from the console then we should be good to go. Let’s start doing some GUI work.
Now what we don’t have is the .* notation on an import, so we won’t get to import the entirety of QT, what’s more we have to make two more modifications to project.clj.
The first thing to do is add the following line to your project.clj inside your dependencies:
add this line beneath your :main statement:
:jvm-opts ["-d32" "-XstartOnFirstThread"]
This will tell Lein to run in 32bit mode and tell QT where to start, both are important to keep it from crashing.
Now in core add these lines directly below your Namespace declaration.
Okay, time to wrap it up by modifying your (main) so that it looks like this:
(QApplication/initialize (into-array [""]))
(.show (new QPushButton “Hello World”))
When you do Lein Run now you should see a very small window with a very informative button on it, one that says Hello World! Congratulations, you’ve taken your first steps into the world of GUI applications with QT and Clojure, and for that matter so have I.
We’ll see where this takes us.
The full source for the sample project can be found at https://github.com/mblake/jambi-hello-world.