11.12.08

GUI toolkit extravaganza part III: WxRuby

In the previous part of the GUI toolkit extravaganza we looked at the FXRuby toolkit. This time we will spend some time to look at the Yin of FXRuby's Yang, the wxRuby toolkit.

wxRuby
wxRuby is a library that enables Ruby code to use the wxWidgets library. wxWidgets is a cross-platform GUI library written in C++. wxRuby has arrived at version 2 so we will look at that one. Not only the name sounds like FXRuby but also it's features seem alike. Let's find out if there are any differences!

ease of installation
xwruby2 is available as a Ruby gem. This makes the installation process very easy. According to the documentation, all you have to do is: sudo gem install wxruby2. There are also binary and source packages are available. On my Ubuntu Hardy Heron system, this did not do the trick however. Apperently there is something else you need to to apart from installing the gem, and this is poorly documented. You can read more about the problems installing wxruby2 in my previous post.

documentation
There seems to be quite a decent ammount of documentation for wxruby2. The project website provides the complete API reference and a Tutorial. As far as I'm aware there are no books about wxruby2, nor have I seen it featured in a book. The project's website hosts two mailinglists.

supported platforms
Wxruby has been created to provide a cross platform GUI toolkit, so it runs on multiple platforms. Systems running Linux, UNIX, Windows or Os/X are all supported by wxruby.

complexity
Take a look at the following code sample. We create a main window and place a button on it. We use PLACEMENT_SCREEN to center it. Piece of cake!

#!/usr/bin/env ruby
#!/usr/bin/env ruby
require 'wx'
Wx::App.run do
frame = Wx::Frame.new(nil, :title => "wxRuby window")
button = Wx::Button.new(frame, :label => 'Button')
evt_button(button) { puts 'WXRuby' }
frame.show
end

functionality
wxruby2 provides a standard set of graphical functions. The focus lies on cross-platform availability and the usage of native window designs. So on a GNOME system, you get GTK look and feel, on and on Mac OS/X you get aqua and on Windows you get the well known theme from Redmond. I am curious though as how much of windows, aqua and gtk functionality is supported...Unfortunately, finding that out would take more time then I have at the moment.

performance
There was some flickering going on at the top of the window sometimes. But I have noticed that on Fxruby windows as well since I upgraded my system to Ubuntu Intrepid. It does not seem like it's a problem caused by any of these two kits. Otherwise this performs just good.

looks
There's not much difference to be seen in the example provided here and the one previously provided in parts I of the GUI toolkit extravaganza. There are some minimal details around the buttons and edges. Reason is that it uses native graphics, so on my system it uses GTK in the end. Instead of adding yet another picture of a window with one button with only miniscule differences. Here's a picture from one of the sample programs, in this case,



You can find the wxruby2 toolkit at:
http://wxruby.rubyforge.org

Next up for the GUI toolkit extravaganza part IV is Shoes!

9.12.08

wxruby: reading error messages about libraries

As you might have noticed, some time has passed since I wrote about fxruby. Wxruby was to follow a few days after it. However I had been experiencing problems getting it to work. With only a few days to go before the Shoes class starts I wanted to put an end to this misery.

First thing people do nowadays when problem solving is to Google for solutions, so did I. Searching for the errors I got did return some mailing list postings from people with the same problem, but no useful answers. As you might have experienced yourself, searching for these kinds of things can quickly take hours without you realizing it. It is not only time consuming, but in the spirit of despair you might just actually try some really stupid recommendation from a person who's most likely just be guessing himself. Actually trying some of their suggestions can add even more problems and make the whole so complex you'll eventually just give up...but then that's not very Ninja, is it?

After installing the wx package I thought I'd only need to install the wxruby gem and be done with it.

sudo gem install wxruby

Unfortunately not so...
ruby -rubygems ./wxtest.rb
/var/lib/gems/1.8/gems/wxruby-1.9.9-x86-linux/lib/wxruby2.so: libwx_gtk2u_stc-2.8.so.0: cannot open shared object file: No such file or directory - /var/lib/gems/1.8/gems/wxruby-1.9.9-x86-linux/lib/wxruby2.so (LoadError)
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:27:in `require'
from /var/lib/gems/1.8/gems/wxruby-1.9.9-x86-linux/lib/wx.rb:12
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require'
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:32:in `require'
from ./wxtest.rb:3
Obviously it had some problems loading the wxruby2.so binary library. This file exists in the specified directory along with wx.rb. The permissions to wxruby2.so were set to readonly, this did not seem right for a binary. Adding execute permissions did not help however.

The problem might have been caused by one of the other errors. One of them seemed to originate from wx.rb. Wx.rb can be found in the same directory as wxruby2.so. This is the file you should require in your ruby code. Basically it loads both the wxruby2.so and ruby extensions to core wx classes. There was something about line 12. Using vim's :set nu command, the apparent culprit was displayed on my screen:
11 # load the binary library
12 require 'wxruby2'
13
14 # alias the module
15 Wx = Wxruby2
There could not be anything wrong about that.

There were however three errors in custom_require.rb. The first impression was, judging from the directory, that this was a generic function used by or for rubygems. Obviously I was not very convinced that this might be the cause of the problem. But it would not hurt to take a look.

First look was at the code near line number 27:
26 def require(path) # :nodoc:
27 gem_original_require path
28 rescue LoadError => load_error
29 if load_error.message =~ /\A[Nn]o such file to load -- #{Regexp.escape path}\z/
Hmm, this code wants a path to some gem thingy, else it throws an error. Not the error I got however. While this seemed illogical at that moment, sometimes one must keep problems simple and not add other problems along the way. The main point was this code wanted some path.

Two other errors were caused at something near line 32.
32 gem_original_require path
33 else
34 raise load_error
No more clues were necessary. The suspect was some unknown path variable. Since wxruby was installed as a gem. My code needed to load rubygems itself. According to the installation manual there's three ways to do this:

* Run ruby with the -rubygems argument: eg ruby -rubygems my_wxruby_script.rb
* Set the RUBYOPT environment variable to -rubygems
* Add require 'rubygems' at the top of your wxruby program.

I had tried running my code with the -rubygems argument allready. And I did use the require 'rubygems' in my code. I did not set the RUBYOPT however, so I removed the require line and set this variable with RUBYOPT="-rubygems".

The same errors lit the screen after I ran my code again. A sense of defeat and disillusion filled my mind, what could be the problem? I had tried countless solutions, analyzed code, read documentation and yet I was no step further. Having no more ideas, I stared blankly at the screen, looking at the errors...

/var/lib/gems/1.8/gems/wxruby-1.9.9-x86-linux/lib/wxruby2.so: libwx_gtk2u_stc-2.8.so.0: cannot open shared object file: No such file or directory - /var/lib/gems/1.8/gems/wxruby-1.9.9-x86-linux/lib/wxruby2.so (LoadError)

Staring back was a half lit reflection of myself. I saw a person who was about to give up as I started to think about skipping this chapter of the GUI Toolkit extravaganza. At least I had Ruby-GTK2 and FXruby...GTK?...What's that gtk doing in my error message!

A quick query in my package management tool found that I did not have any libwx_gtk* libraries installed, why would I. The documentation certainly did not write about needing this library! I did encounter it while searching for ruby & wx libraries, but never made the connection...

Anyway, there were some dependencies and here's what was installed:

libwxgtk2.6-0
libwxgtk2.6-dev
libwxbase2.6-0
libwxbase2.6-dev
libwxgtk2.8-0
libwxgtk2.8-dev
libwxbase2.8-0
libwxbase2.8-dev

After this I could run the examples that come with wxruby. Looking back at the errors I wonder, did you overlook this one in the error messages as well?

Comming up: Part III of the GUI toolkit extravaganza, featuring wxruby!