Forum: wxRuby Stuck noobie: XRC/xrcise woes

3754be88848f5939d10270ca97955eba?d=identicon&s=25 John Davidson (rankbeginner)
on 2010-06-22 09:27
Hi,

I'm teaching myself to use wxRuby and DialogBlocks to create a front end
for a Ruby program I wrote. And I'm hopelessly stuck!

In DialogBlocks (or indeed wxFormBuilder, which gives me the same
problem) I can create a widget, give that widget a new id and class name
(in the example I created below, text_box1 and CaseChangeTextCtrl1,
respectively), and then add a module which utilises that widget in my
program, no problem.

But the moment I try to add a second widget with a second id and a
second class, (in the example below, text_box2 and CaseChangeTextCtrl2 )
I get an "uninitialized constant" error for that widget when I run my
program. I don't understand it at all. The two widgets are the same,
except they have different class names and different id names.

Is there some limit (a limit of 1) to the number of classes you can
create in an XRC file or xrcise-generated rb file? Do you have to get
DialogBlocks to create separate files for each new class apart from the
first class, or something?

I am sure I am missing something simple. But I have spent hours on this,
and can't figure it out. Please! Help! Me!

warm regards

John

Below is everything in the chain: 1) the xrc file created by
dialogblocks; 2) the rb file generated from that xrc file by xrcise
(this is the file that produces the error); 3) the user-written code (in
this case, an exercise taken from the web) that calls that
xrcise-generated rb file; and 4) the error message.




1)
###### the xrc file #####
<?xml version="1.0" encoding="UTF-8"?>
<resource version="2.3.0.1" xmlns="http://www.wxwidgets.org/wxxrc">;
    <object class="wxFrame" name="ID_WXFRAME" subclass="TextFrameBase">
        <style>wxCAPTION|wxRESIZE_BORDER|wxSYSTEM_MENU|wxCLOSE_BOX</style>
        <size>400,300</size>
        <title>From Scratch</title>
        <centered>1</centered>
        <object class="wxBoxSizer">
            <orient>wxVERTICAL</orient>
            <object class="sizeritem">
                <flag>wxGROW|wxALL</flag>
                <border>5</border>
                <option>1</option>
                <object class="wxTextCtrl" name="text_box1"
subclass="CaseChangeTextCtrl1">
                    <style>wxTE_MULTILINE</style>
                </object>
            </object>
            <object class="sizeritem">
                <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
                <border>5</border>
                <object class="wxButton" name="upper_bt">
                    <label>Upper</label>
                </object>
            </object>
            <object class="sizeritem">
                <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
                <border>5</border>
                <object class="wxButton" name="lower_bt">
                    <label>Lower</label>
                </object>
            </object>
            <object class="sizeritem">
                <flag>wxGROW|wxALL</flag>
                <border>5</border>
                <option>1</option>
                <object class="wxTextCtrl" name="text_box2"
subclass="CaseChangeTextCtrl2">
                    <style>wxTE_MULTILINE</style>
                </object>
            </object>
        </object>
    </object>


2)
######## the ruby file generated by xrcise ######
# This class was automatically generated from XRC source. It is not
# recommended that this file is edited directly; instead, inherit from
# this class and extend its behaviour there.
#
# Source file: exercise.xrc
# Generated at: Tue Jun 22 16:49:12 +1000 2010

class TextFrameBase < Wx::Frame

     attr_reader :text_box1, :upper_bt, :lower_bt, :text_box2

     def initialize(parent = nil)
          super()
          xml = Wx::XmlResource.get
          xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
          xml.init_all_handlers
          xml.load("exercise.xrc")
          xml.load_frame_subclass(self, parent, "ID_WXFRAME")

          finder = lambda do | x |
               int_id = Wx::xrcid(x)
               begin
                    Wx::Window.find_window_by_id(int_id, self) || int_id
               # Temporary hack to work around regression in 1.9.2;
remove
               # begin/rescue clause in later versions
               rescue RuntimeError
                    int_id
               end
          end

          @text_box1 = finder.call("text_box1")
          @text_box1.extend(CaseChangeTextCtrl1)
          @upper_bt = finder.call("upper_bt")
          @lower_bt = finder.call("lower_bt")
          @text_box2 = finder.call("text_box2")
          @text_box2.extend(CaseChangeTextCtrl2) #<<<<< THIS IS THE BAD
LINE THAT CAUSES THE ERROR
          if self.class.method_defined? "on_init"
               self.on_init()
          end
     end
end

3)
######## Exercise.rb ########
require 'rubygems'
require 'wx'
 # load in the generated code
 require 'my_frame'

 # Mix-in for a Wx::TextCtrl
 module CaseChangeTextCtrl1
   # convert all the text in the control to upper case
   def upcase!
     self.value = self.value.upcase
   end
   # convert all the text in the control to lower case
   def downcase!
     self.value = self.value.downcase
   end
 end

 # Inherit from the generated base class and set up event handlers
 class CaseChangeFrame < TextFrameBase
   def initialize
     super
     evt_button(upper_bt) { text_box1.upcase! }
     evt_button(lower_bt) { text_box1.downcase! }
   end
 end

 # Run the class
 Wx::App.run do
   CaseChangeFrame.new.show
 end

4)
##### ERROR MESSAGE: #####
R:\GUI\Practice\Exercise>ruby Exercise.rb
./my_frame.rb:37:in `initialize': uninitialized constant
TextFrameBase::CaseChangeTextCtrl2(NameError)
        from Exercise.rb:21:in `initialize'
        from Exercise.rb:29:in `new'
        from Exercise.rb:29:in `on_init'
        from
C:/Ruby187/lib/ruby/gems/1.8/gems/wxruby-2.0.1-x86-mingw32/lib/wx/classes/app.rb:16:in
`main_loop'
        from
C:/Ruby187/lib/ruby/gems/1.8/gems/wxruby-2.0.1-x86-mingw32/lib/wx/classes/app.rb:16:in
`run'
        from Exercise.rb:28
3754be88848f5939d10270ca97955eba?d=identicon&s=25 John Davidson (rankbeginner)
on 2010-06-22 09:44
Dont worry. Figured it out. I was writing empty modules for the new
classes, thinking that would suffice as I went along, but I need to put
some placeholder functions into them.

cheers

John
This topic is locked and can not be replied to.