Tag Archives: gtk-fortran

Creating a GUI using GTK3 and gtk-fortran

Update (6/26/14): If you downloaded the old project template .zip I first had up here, you probably couldn’t get the window to load.  That’s because the test.glade file in the template had the signals (and the objects) named incorrectly, so the window would never launch.  I’ve since made corrections and uploaded the fixes to here:

https://github.com/jshahbazi/fortran-gui-demo

I’ve also completely rewritten that section of the post so there won’t be anymore confusion.  If you have no idea what I’m talking about then don’t worry about it…  Everything is great 🙂


Update (6/27/14): I’ve gone ahead and re-written a major of the second half of the post to include some basic concepts for what you’re doing and also to make the steps a bit more clear.


 

Original Post:  

If there’s one thing that I’ve struggled with in the past year, its been finding an easy way to create a GUI using Fortran.  While I haven’t actually spent an entire year trying to figure it out, I certainly have stumbled during those times when I did try.  I even attempted to make my own library based on gtk-fortran, but then I realized that I was just making things more complicated than they needed to be.  Rather than try and reinvent the wheel, I abandoned the project.

Recently though, I have come across a relatively pain-free way of doing it.  First, a little bit of an introduction:

There are several libraries available to make a GUI, but most don’t have a GUI to make a GUI (i.e. a RAD tool).  You can use DISLIN to code a GUI, and it certainly can turn out nice.  But because you have to code it by hand and then compile/run to see if you did it right, it can be a lot of work.  And unfortunately, I’m really lazy (in public I call it being “pragmatic”).  Not to mention for anything other than your own little home project it costs money to license.  There are other GUI libraries around (Winteracter, GINO), but they cost money, too.  What we need is a free one that you can build a fully-functional program with most of the bells and whistles.

Enter GTK and Glade.

GTK, if you didn’t know already, is an open-source, cross-platform API written in C that’s for creating graphical user interfaces.  In order to interface that into Fortran, gtk-fortran was created.  It is a “partial GTK+ / Fortran binding 100% written in Fortran.”  To do such binding, the ISO_C_BINDING module is used.  The current version of GTK+ is v3.x, so we’ll be concentrating on that rather than the previous v2.x.

Using GTK and gtk-fortran alone, you can create the entire GUI.  But why do that when there’s Glade?  Glade is a RAD tool to make GUIs for GTK, and it works really well.  You can read more about it on its own page, but if you’re going to download it, you should look at glade-main-page-thumbgetting v3.18.x, which is for GTK 3.  There’s another version, 3.8.x, but that’s for GTK 2.   Now, I have mixed up Glade files and used ones that were designed for GTK 2, but I wouldn’t recommend it.

So now you’ve got a library and a GUI for making your GUI.  What next?  How do you put it all together?  That can be a lot harder than it sounds, even for someone that’s experienced.  I struggled for a while until I found this webpage put together by Darius Markauskas:  http://darmar.vgtu.lt/notes/10-gtk-fortran

He goes through the steps of putting everything together and even graciously provides links for a couple of Code::Blocks Fortran projects to demonstrate.  He really has everything there.  So why am I writing this?  Well, for coverage of the topic.  And also because I want to try to simplify the process as much possible.  So, I’m going to cut the steps down and also include a bare-bones project template for Code::Blocks.  That way you’ll be able to create a new project directly from the template with the absolute essentials (and a tiny little demo from the original project by Markauskas).


New stuff:  

Some basic concepts before we begin:

Think of your program as having several different levels of things you need work with.  The bottom level is all the GTK code that draws stuff on screen.  You won’t be messing with any of that.  In fact, you can’t see any of it since its stuffed away in a compiled library in the \GTK3\bin folder.  The next level up is the gtk-fortran code, which calls the GTK code.  Its written in Fortran and visible for you to work with and modify.  However, I would highly recommend against this.  What you’re going to do instead is call the subroutines and functions of gtk-fortran (and provide specific arguments) in your own code, which is the next level up.  Within your own code, you’ll be using things like call gtk_init() and call gtk_widget_show_all(window) to do the heavy-lifting for you.  But, you’ll also need to actually arrange the layout of the GUI and give the various pieces names.  In theory, you can do this in code, but its very cumbersome.  What we want to do is to create a separate file, outside any of the code, with the layout and names and use the Glade editor to work with it.  That way, we can visually see what it will look like and generally have a much easier time when putting it together.  That file will essentially be the highest level up.  It’s really just an XML file with the names of things, their locations, and signals that are associated with “stuff.”  What are signals?  Well, if you’ve never worked with a GUI before, signals are basically specifically-named “signals” that are broadcast by the program when something is done.  So let’s say you click a button.  A “clicked” signal is sent out.  In Glade, you’ve assigned this particular “clicked” signal a unique name that you can use later on.  That unique name is called the “handler name” (yes, its a bit confusing but you’ll get used to it).  You assign the handler the name “button_hello_clicked.”  Every time you click that button, that “clicked” signal is broadcast through the program with the handler name “button_hello_clicked.”  But you, of course, want something to happen when you click a button.  So there are gtk-fortran functions that look for these signals.  You can set up the program using those functions so that whenever it sees a specific signal, it will call a function you specifically designate.  For instance, take a look at the code below:

select case (h_name)
case (“button_hello_clicked”)
call g_signal_connect (object, signal_name, c_funloc(button_hello_clicked), c_this)

case (“button_quit_clicked”)
call g_signal_connect (object, signal_name, c_funloc(button_quit_clicked), c_this)

end case

The above is code from the demo project that I’ve made available below.  The h_name is the handler name of signal.  So the select case is setting up for all the possible signals that could be broadcast.  The call g_signal_connect is a subroutine that then connects that signal to a function of your choice.  Within the arguments for g_signal_connect is c_funloc(button_hello_clicked).  The c_funloc is always required.  You don’t need to know all the details of it, but its a C thing that you need for GTK to know stuff.  What’s more important is the button_hello_clicked.  That’s the actual name of the function in your program that you want to associate with the button being clicked.

And that’s it.  That’s all you need to do.

Well, for the most part.

There’s a lot more you can do, sure, but the above is the very most basic concept you need to get started.


 

Edited Stuff:  

Steps to get your GUI up and running:

  1. Make sure you have a Fortran compiler and the Code::Blocks IDE
  2. Download the GTK+ 3.x All-In-One bundles (for example, choose the Windows 32-bit platform and then download this All-In-One bundle) and install it to same base directory that you keep your project folders in.  Well, you don’t really have to, but it’ll make things easier.  For example, using the base directory of C:\dev, we’ll eventually have C:\dev\GTK3 (for GTK) and C:\dev\fortran-gui-demo (for your project)
  3. This is very important: Add the bin folder of the above GTK path (e.g. C:\dev\GTK3\bin) to your PATH variable or equivalent.  When you run the program, its going to look for a number of libraries in the GTK3\bin folder.
  4. Download gtk-fortran from the gtk-fortran GitHub page (using the “Download ZIP” button on the right side of the page).  You don’t need this for the demo project I provide, but you’ll need it for the future.
  5. Download Glade so you can edit the GUI’s .glade file later if you want.  Remember, this is the program that you use to visually arrange the GUI’s layout and assign the handler names to the signals.  You may want to download the source for Glade and compile it yourself, so you can go here for that (remember, grab v3.18 or higher).  If you don’t want to compile it, you can download a precompiled binary (even though its only v3.14, it should work fine).
  6. Download this demo project and load it with CodeBlocks:  https://github.com/jshahbazi/fortran-gui-demo

You’ll notice that in the demo project, there is a directory called gtk_src.  This is the gtk-fortran files that I mentioned you wouldn’t have to worry about for now.  Its simply a convenience that they’re there.  Also notice the test.glade file.  Once you load the project in CodeBlocks, you’ll even see it listed as one of the files.  That’s another little thing I did to make things a bit easier.  That’s not normally going to happen.  You’ll specify in the code itself what .glade file you’re using (see call create_window(demo_win,”test.glade”//c_null_char) )

Keep in mind, too, that I really just changed a bunch of things around in the code from the original say_hello project by Markauskas to make things a little easier to understand.  If you’re still having trouble, go to his page and try working through his directions.  They might work better for you.

ForGE Compilation Issues

So the instructions for compiling ForGE were lacking the linker arguments for gtk-fortran (which is required). Technically, I did say that gtk-fortran was a requirement, but I suppose my goal to help simply Fortran development wasn’t quite met by leaving that part out. However, I have fixed the readme.txt file to reflect the proper linker arguments that are required. Sorry.

And I had previously left out the forge.mod file that was required to compile the entire framework. So yeah, that’s in there now. Everything should work. Please let me know if it doesn’t.

Finally, I haven’t updated the instructions or the wiki to reflect the new functions/widgets that are available. I will soon. But until then, the test.f90 file should give several examples of how to use them.

On a brighter note, the framework is starting to come together to look much better. Widget placement looks better, and I’m gaining finer control over each piece. I’m currently attempting to incorporate PLPlot into the whole thing, so graphing will soon be available (I hope).

ForGE v0.4.0

Version 0.4.0 of the ForGE framework has been released. Several new widgets (including cairo drawing surfaces) have been added, internal tweaks to the how widgets are placed, sized, and displayed have been made, and some new functions have been added.

ForGE Instructions!

Instructions are now available for the ForGE framework. Please visit https://sourceforge.net/projects/fortran-forge and download the instructions.txt file.

ForGE v0.3.1

Version 0.3.1 of the ForGE framework has been released: https://sourceforge.net/projects/fortran-forge

The code has been rewritten to move to an object-oriented, static-library design. Documentation is severely lacking for now.

Changes to this version include:

  • Completely rewrote codebase to change to object-oriented design
  • More widgets added

ForGE v0.2

Version 0.2 of the ForGE framework has been released: https://sourceforge.net/projects/fortran-forge

Changes to this version include:

  • Finished converting to object containers for each window, no more global variables for that
  • Changed named of handlers module to event_handlers for clarity
  • Added additional widget procedures: create_button, create_text_entry
  • Added example event handlers for new widgets

ForGE v0.1

I’ve been doing some research for the past couple of months on how to go about making a GUI in Fortran and during that time I’ve experimented with DISLIN, GTK+ (through gtk-fortran), and Intel’s QuickWin framework.

QuickWin seems to be a quick and dirty way to get code outputting into a non-command prompt window, and while it works well for that, its not good for more complicated GUI development.

DISLIN is an excellent and fast way to put together a GUI using procedure calls, however the licensing of it cannot be used in an open source manner. Its free for individual research use, but it cannot be distributed. Aside from that – and the arcane function naming scheme – its an excellent and time-tested framework.

gtk-fortran and its port of GTK+ is more new. It isn’t as simple as DISLIN to throw together a GUI, but it *is* open source. Because of this, I decided to use it as a GUI framework.

Overall, after a few days of frustration, I was able to figure out how to use gtk-fortran and also its high-level API. I realized that I could easily package a lot of the functions into a simple set of procedure calls that hopefully even novice Fortran developers could use without much trouble.

And so, I began to do just that.

Along the way, however, I realized that with this framework the program that would finally be developed would be entirely event-based – a typical GUI program. That may be perfectly fine for most developers, but in my case I needed a process to run on its own in the background regardless of the GUI’s involvement.

After a good amount of time learning how to incorporate OpenMP into a program, I added aspects of it into my framework to allow the GUI to run on its own thread while background procedures run on other threads. If no background processes are necessary, the framework will run perfectly fine without them. A developer can easily create an event-based Fortran program just by putting together the GUI through the very high-level procedure calls and then creating event handlers, just as in most other languages with RAD tools (for the most part).

This is just the first alpha release of it. I don’t have all the instructions in there, and I don’t have all the GUI procedures done. I’m even only halfway through putting the main window creation onto an object-oriented path (it still works just fine, though).

Future plans include some form of OpenCL. While OpenACC is eventually going to be merged into OpenMP, I figure that for now a little OpenCL wouldn’t hurt anyone.

Enjoy: sourceforge.net/projects/fortran-forge/

I welcome all criticism. Constructive and non-constructive.