Writing a Searchable Dictionary with Ruby and wxWidgets
Written By: Nathan Baker
- 29 May 2006 -
Description: For today's Ruby lesson, we will explore the creation of a simple GUI, and then create an interface allowing us to search a user-created dictionary.
Part 4: Making it actually do something
Despite all this verbage, the observant reader will notice that the application still doesn't do anything. I mean, sure it processes a text file and displays a form, but so what? The button just sits there and mocks you when you click it. Well, it's time to change that by using wxWidgets' events. This is one of the reasons I chose wxWidgets: in this respect, it is the most Ruby-like of all the GUI frameworks. The following code belongs in the constructor:
evt_button(btnLookup.get_id) {|event| doLookup(event)} evt_text_enter(get_id) {|event| doLookup(event)}
Then, put the following method in that same class:
def doLookup(event) if .has_key?(get_value) set_label([get_value]) else set_label('No results') end end
Remember that since we let wxWidgets assign the ids for those controls, we need to ask the control what its id is. You could, of course, also hard-code the ids, but this is a pain when you delete one control and add another and then can't remember which id you're on...much better to let that sort of thing be automatically handled.
OK, so it's pretty simple. Every time the event is fired, the given code block is executed. We could have included the doLookup method inline, of course, but since we would have to write it twice then it's better off in its own function.
So, nothing fancy here. We just check to see if the dictionary has the key and then display the result, or a suitable not found method if there is no result.
Now you have the whole thing. Note that if you have your Dictionary and DictionaryFrame classes in different files (like me), you will need to say something like require 'dictionary.rb' at the top of the file. I'll include the whole GUI file here to help disguise the fact that this section is so short:
require 'wxruby' require 'Dictionary.rb' require 'FilenameParser.rb' include Wx class DictionaryFrame < Frame def initialize(dict, parent=nil, id=-1, title='', pos=DEFAULT_POSITION, size=DEFAULT_SIZE) style = MINIMIZE_BOX | SIMPLE_BORDER | SYSTEM_MENU | CAPTION super(parent, id, title, pos, size, style) = dict pnlMain = Panel.new(self, -1) = TextCtrl.new(pnlMain, -1, '', Point.new(15, 15), Size.new(100,20), TE_PROCESS_ENTER) btnLookup = Button.new(pnlMain, -1, 'Look Up', Point.new(120, 15), Size.new(60, 20)) = StaticText.new(pnlMain, -1, '', Point.new(15,45), Size.new(100, 20)); evt_button(btnLookup.get_id) {|event| doLookup(event)} evt_text_enter(get_id) {|event| doLookup(event)} end def doLookup(event) if .has_key?(get_value) set_label([get_value]) else set_label('No results') end end end class DictionaryApp < App def on_init d = Dictionary.new(FilenameParser.Parse) DictionaryFrame.new(d, nil, -1, 'Dictionary Tool', Point.new(400, 300), Size.new(200, 100)).show end end DictionaryApp.new.main_loop
Well, there you go. If you're having trouble coming up with a dictionary file of your own, here's one you can use:
A Aardvark
B Baboon
C Chameleon
D Dingo
E Emu
F Flamingo
G Gnu
H Hedgehog
I Ibis
J Jackal
K Koala
L Lemur
M Moth
N Narwhal
O Opossum
P Platypus
Q Quail
R Reindeer
S Sea Slug
T Tarantula
U Urial
V Vole
W Wildebeest
X Xenops
Y Yak
Z Zeren
Yep, if you type in a (capital English) letter, it will tell you an animal whose name begins with that letter. Obviously I was struggling for U, X, and Z. Whatever.
So that's it! As always, I'm at [] if you have any questions, comments, proclamations, abbreviations, expectorations, or...well...yeah. Code to live!