Hi folks
I''m trying to make a class to make Wx::Menu easier for me to use and
hide the constants and event-binding complexity.
I''ve created a subclass of Wx::Menu, but whether I create my own
append() method and call super(), or create a differently-named method
and called append() from it, it seems to segfault. Sample attached, see
line 20. Am I doing something stupid?
Also, perhaps someone could check that I''m doing the passing around of
event-handling blocks correctly ... unfortunately I can''t get that far
yet ...
cheers
alex
-------------- next part --------------
require ''wxruby''
class EasyMenu < Wx::Menu
def EasyMenu.next_base()
@base_range ||= 0
@base_range += 100
end
def initialize(target)
@target = target
@base_id = EasyMenu.next_base()
@commands = {}
end
# adds a menu item with the title +command_str+, optionally bound to
# the shortcut key +command_key+, and binds the menu item to the
# block argument. Returns a symbol which can be later used to
# identify the menu item to other arguments
def add_menu_item(command_str, command_key = '''')
const = ( @base_id += 1 )
ident = command_str.gsub(/\s+/, "_").gsub(/\W/,
"").downcase.to_sym
@commands[ident] = const
# WHY DOES THIS SEGFAULT?!
append(const, "#{command_str}\t#{command_key}")
# IS THIS THE RIGHT WAY TO PASS ON THE PASSED-IN EVENT-HANDLING BLOCK?
@target.evt_menu(const) { | e | yield e }
return ident
end
def enable_items(*idents)
idents.each { | ident | enable( @commands[ident], true ) }
end
def disable_items(*idents)
idents.each { | ident | enable( @commands[ident], false ) }
end
end
class MyFrame < Wx::Frame
def initialize(title, x, y, w, h)
super(nil, -1, title, Wx::Point.new(x, y), Wx::Size.new(w, h))
end
end
class MyApp < Wx::App
def on_init()
frame = MyFrame.new(''EasyMenu'', 50, 50, 400, 200)
# @menu_foo = Wx::Menu.new()
# @menu_foo.append(999, "&Qux\tCtrl-Q")
# frame.evt_menu(999) { | e | p "QUX" }
@menu_foo = EasyMenu.new(frame)
@menu_foo.add_menu_item("&Qux", "Ctrl-Q") { | e | p
"QUX" }
menu_bar = Wx::MenuBar.new()
menu_bar.append(@menu_foo, "&Foo")
frame.set_menu_bar(menu_bar)
frame.show(TRUE)
end
end
MyApp.new.main_loop()
Hi Alex,
Your problem is on line 10 of your program. You need to correctly call
the Wx::Menu constructor. Note the call to super()
def initialize(target)
super() # NOTE THIS LINE
@target = target
@base_id = EasyMenu.next_base()
@commands = {}
end
For some reason just saying "super" doesn''t do it and you
need the "(
)" after it. HTH,
Zach
Fixed it - thanks! Zach Dennis wrote:> Hi Alex, > > Your problem is on line 10 of your program. You need to correctly call > the Wx::Menu constructor. Note the call to super() > > def initialize(target) > super() # NOTE THIS LINE > @target = target > @base_id = EasyMenu.next_base() > @commands = {} > end > > For some reason just saying "super" doesn''t do it and you need the "( > )" after it. HTH, > > Zach > _______________________________________________ > wxruby-users mailing list > wxruby-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users > >
> For some reason just saying "super" doesn''t do it and you need the > "()" after it. HTH,FYI, this is a general Ruby issue: calling "super" passes the parameters received to the parent method, so in this case it is equivalent to "super(target)". Since the parent methods doesn''t expect parameters and is in C++ you get the segfault. Calling "super()" forces it to call the parent method without params.
Mehr, Assaph (Assaph) wrote:>>For some reason just saying "super" doesn''t do it and you need the >>"()" after it. HTH, >> >> > >FYI, this is a general Ruby issue: calling "super" passes the parameters >received to the parent method, so in this case it is equivalent to >"super(target)". Since the parent methods doesn''t expect parameters and >is in C++ you get the segfault. Calling "super()" forces it to call the >parent method without params. > >Very good to know, your comments are very much appreciated Assaph. Keep''em coming. ;) Zach
Mehr, Assaph (Assaph) wrote:> Since the parent methods doesn''t expect parameters and > is in C++ you get the segfault. Calling "super()" forces it to call the > parent method without params.Still, wxruby shouldn''t segfault no matter what you throw at it. I would appreciate if someone (Alex?) could enter this as a bug in our rubyforge tracking system. If we do a 0.6 based on the non-swig code, I would like to fix this so it handles it more gracefully. Thanks, Kevin
Just to double-check, what I''m getting is "This application has requested the Runtime to terminate it in an unusual way." or something like that, and no normal close-down happens. That is a segfault, yeah? If so, I do get that in a few circumstances with WxRuby, when I do something like calling methods with inappropriate argtypes. I can happily bug list these if that''s useful. I did wonder a while back if there was a more helpful way of exiting in these cirucmstances, eg with a line no. cheers alex Kevin Smith wrote:> Mehr, Assaph (Assaph) wrote: > >> Since the parent methods doesn''t expect parameters and >> is in C++ you get the segfault. Calling "super()" forces it to call the >> parent method without params. > > > Still, wxruby shouldn''t segfault no matter what you throw at it. I would > appreciate if someone (Alex?) could enter this as a bug in our rubyforge > tracking system. If we do a 0.6 based on the non-swig code, I would like > to fix this so it handles it more gracefully. > > Thanks, > > Kevin > _______________________________________________ > wxruby-users mailing list > wxruby-users@rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users > >
alex fenton wrote:> Just to double-check, what I''m getting is "This application has > requested the Runtime to terminate it in an unusual way." or something > like that, and no normal close-down happens. That is a segfault, yeah?Sounds like it to me.> If so, I do get that in a few circumstances with WxRuby, when I do > something like calling methods with inappropriate argtypes. I can > happily bug list these if that''s useful.The "perfect" way to report these would be to find a (very) small app that demonstrates the problem, and post it here to the list. That way, I can be sure I can reproduce it. Then write it up as a bug. Thanks much, Kevin