rsram312
rsram312

Reputation: 31

QtRuby: Stack Level too deep (SystemStackError)

I have the following code:

require 'qt'

class Menu < Qt::Widget
  slots 'on_clicked_uAuth()'
  slots 'quit()'

  def initialize(parent = nil)
    super(parent)
    setWindowTitle "Menu"
    uAuth_ui
    exit_ui
    resize 350, 500
    move 300, 300
    show
  end
  def uAuth_ui
    uAuth = Qt::PushButton.new 'Auth', self
    uAuth.resize 150, 35
    uAuth.move 100, 100
    connect uAuth, SIGNAL('clicked()'), self, SLOT('on_clicked_uAuth()')
  end
  def exit_ui
    exit = Qt::PushButton.new 'Exit', self
    exit.resize 120, 40
    exit.move 115, 420
    connect exit, SIGNAL('clicked()'), self, SLOT('quit()')
  end
end

app = Qt::Application.new(ARGV)
Menu.new
app.exec

When I click either button, I get the following error:

stack level too deep (SystemStackError)

Can someone let me know what changes I should make so that, when I click the buttons, I get the next screen?

Upvotes: 1

Views: 271

Answers (1)

evotopid
evotopid

Reputation: 5429

First of all, I had to change require 'qt' to require 'Qt' on my system, because I use a case-sensitive filesystem and just because of compatibility reasons I would recommend using the correct case.

Once I was able to run your script I realized the stack trace is really just the SystemStackError message you provided. So I looked a bit around and found a useful snippet here: (Apparently you don't need this in Ruby 2.2 anymore but I don't have it installed right now so I didn't bother trying out)

set_trace_func proc {
  |event, file, line, id, binding, classname| 
  if event == "call"  && caller_locations.length > 500
    fail "stack level too deep"
  end
}

You add this somewhere before executing the app and the stack trace will already be more useful:

from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:2531:in `debug_level'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:2714:in `do_method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:2711:in `do_method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:2667:in `do_method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `qt_metacall'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `qt_metacall'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `method_missing'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `qt_metacall'
from /usr/lib/ruby/vendor_ruby/2.1.0/Qt/qtruby4.rb:469:in `method_missing'

So somehow it got stuck in an endless loop of calling a method that is not present (therefore stack level ends up being too deep).

Now I wasn't able to fix your issue, but it seems that some method is missing. I can't see a declaration of on_clicked_uAuth() anywhere and I'm not sure either if quit() can be accessed with the SLOT like that.

Update: I'm pretty certain now the issue is the SLOT invocation. For example this works perfectly fine:

connect(exit, SIGNAL(:clicked)) { puts "Hello world." }

Now the problem here is that quit is not implemented on QtWidget but rather on the application. However you can just close the window and the application will terminate by default if there are no more windows open:

connect(exit, SIGNAL(:clicked)) { close() }

Upvotes: 0

Related Questions