Undefined method (XRC problem)


#1

I’m trying to get my first small test wxRuby app up and running. I have
created an XRC file using DialogBlocks and then used xrcise to produce
the ruby code which loads it. I then did a bit of cutting and pasting to
produce my own ruby code to add functionality. However I keep running
into the same problem of ‘undefined method’. I’ve tried lots of
different alternatives to get_selection (ie, value, get_value,
get_item_data etc but with no luck).

I’m sure I’m doing something wrong that someone will find to be a basic
error (hopefully!). Happy to post XRC file if necessary. Any help
gratefully appreciated.

___ The error message:__________________________________________________

$ ruby xrctest.rb
xrctest.rb:10:in generatetext': undefined methodget_selection’ for
nil:NilClass (NoMethodError)
from xrctest.rb:18:in initialize' from /usr/lib/ruby/gems/1.8/gems/wxruby-1.9.10-x86_64-linux/lib/wx/classes/app.rb:16:incall’
from
/usr/lib/ruby/gems/1.8/gems/wxruby-1.9.10-x86_64-linux/lib/wx/classes/app.rb:16:in
process_event' from /usr/lib/ruby/gems/1.8/gems/wxruby-1.9.10-x86_64-linux/lib/wx/classes/app.rb:16:inon_run’
from
/usr/lib/ruby/gems/1.8/gems/wxruby-1.9.10-x86_64-linux/lib/wx/classes/app.rb:16:in
main_loop' from /usr/lib/ruby/gems/1.8/gems/wxruby-1.9.10-x86_64-linux/lib/wx/classes/app.rb:16:inrun’
from xrctest.rb:23

Xrcise produced this (myframe.rb):_______________________________

class FrameBaseClass < Wx::Frame
attr_reader :id_choice_select, :id_datectrl, :id_button_test,
:id_textctrl_test, :id_button_close

def initialize(parent = nil)
super()
xml = Wx::XmlResource.get
xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
xml.init_all_handlers
xml.load(“testwindow.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

@id_choice_select = finder.call("id_choice_select")
@id_datectrl = finder.call("id_datectrl")
@id_button_test = finder.call("id_button_test")
@id_textctrl_test = finder.call("id_textctrl_test")
@id_textctrl_test.extend(ClassTextCtrl)
@id_button_close = finder.call("id_button_close")
if self.class.method_defined? "on_init"
  self.on_init()
end

end
end

And my own code (xrctest.rb):_______________________________

require ‘rubygems’
require ‘wx’

load in the generated code

require ‘myframe’

Mix-in

module ClassTextCtrl
def generatetext
self.value = @id_choice_select.get_selection
end
end

Inherit from the generated base class and set up event handlers

class FrameBase < FrameBaseClass
def initialize
super()
evt_button(id_button_test) { id_textctrl_test.generatetext }
end
end

Run the class

Wx::App.run do
FrameBase.new.show
end


#2

Hi Rooby N.,

@id_choice_select = finder.call(“id_choice_select”)

It look like your xrc file lack or mispelled the name
“id_choice_select”.

bio.


#3

@id_choice_select = finder.call(“id_choice_select”)

It look like your xrc file lack or mispelled the name
“id_choice_select”.

Fabio - thanks for your suggestion but I’m not sure that’s the case or
indeed the problem here. Still no luck with this - any other ideas
gratefully appreciated.


#4

The problem is, two things that I can see. First, I don’t see where
your
actually mixing in the module ClassTextCtrl into the instance of
id_textctrl_test.

You need to do something like this in your initialization function:

class << @id_textctrl_test
extend ClassTextCtrl
end

Second, your trying to access an instance variable that is defined in
the
FrameBase class, from the TextCtrl class. Which is where your nil is
coming
from. My suggestion would be to do this in your module function:

def generatetext
self.value = self.parent.id_choice_select.get_selection
end

This should solve your problem, and make it work properly.


#5

Rooby N. wrote:

Fabio - thanks for your suggestion but I’m not sure that’s the case or
indeed the problem here. Still no luck with this - any other ideas
gratefully appreciated.

It’s because @id_choice_select is an instance variable of the
FrameBaseClass instance. When you are in the method generatetext, “self”
is the TextCtrl, not the Frame.

If you were to rewrite the event handler as:

evt_button(…) { id_textctrl_text.value = id_choice_select.selection }

it should work

a


#6

Mario S. wrote:

The problem is, two things that I can see. First, I don’t see where
your actually mixing in the module ClassTextCtrl into the instance of
id_textctrl_test.

Mario - the code that xrcise generates does this for you. If you define
a “subclass” for a widget in the XRC editor, xrcise will generate code
that does

@widget.extend SubClass

which is all you need; this is too much, I think:

class << @id_textctrl_test
extend ClassTextCtrl
end

cheers
alex


#7

Some great suggestions here guys, many thanks again for taking the time
to come to the rescue. I’ve had a number of successes based on your
suggestions and I’m now starting to pick up some speed in developing in
wxRuby (and finally starting to have some fun in the process).