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