"Segmentation fault" with QtRuby

A

Arturo Bonechi

Hello everyone!

Using QtRuby, I tried to implement the "Read-only example model"
(Creating new models chapter) of the "Model/View programming" technology
section of Qt Assistant.

But when I launch the example, I got this error :
main.rb:5: [BUG] Segmentation fault
ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]

Abandon

Here is the code :
# slmodel.rb
class SLModel < Qt::AbstractListModel
def initialize string_list, parent = nil
super parent

@string_list = string_list
end

def rowCount parent = Qt::ModelIndex.new
@string_list.length
end

def data index, role
return Qt::Variant.new unless index.isValid
return Qt::Variant.new if index.row >= @string_list.length

return @string_list[index.row] if role == Qt.DisplayRole

Qt::Variant.new
end

# def headerData section, orientation, role = Qt.DisplayRole
# return Qt::Variant.new if role != Qt.DisplayRole
#
# if orientation == Qt.Horizontal
# "Column #{section}"
# else
# "Row #{section}"
# end
# end
end

# window.rb
require 'slmodel'

class Window < Qt::Widget
def initialize parent = nil
super parent

@list = %w[Alpha Beta Gamma Omega]
@model = SLModel.new @list, self
@view = Qt::ListView.new

@view.setModel @model

layout = Qt::VBoxLayout.new
layout.addWidget @view

setLayout layout
end
end

# main.rb
require 'Qt4'
require 'window'

a = Qt::Application.new ARGV
window = Window.new
window.show
a.exec

As the error message doesn't give me that much explanations, I don't
know what is the origin of the problem...
Is it because I forgot to implement some virtual methods from
Qt::AbstractListModel?

Thanks!
 
S

Stefano Crocco

|Hello everyone!
|
|Using QtRuby, I tried to implement the "Read-only example model"
|(Creating new models chapter) of the "Model/View programming" technology
|section of Qt Assistant.
|
|But when I launch the example, I got this error :
|main.rb:5: [BUG] Segmentation fault
|ruby 1.8.7 (2010-01-10 patchlevel 249) [i486-linux]
|
|Abandon
|
|Here is the code :
|# slmodel.rb
|class SLModel < Qt::AbstractListModel
| def initialize string_list, parent = nil
| super parent
|
| @string_list = string_list
| end
|
| def rowCount parent = Qt::ModelIndex.new
| @string_list.length
| end
|
| def data index, role
| return Qt::Variant.new unless index.isValid
| return Qt::Variant.new if index.row >= @string_list.length
|
| return @string_list[index.row] if role == Qt.DisplayRole
|
| Qt::Variant.new
| end

The problem with your code is that the #data method must always return a
Qt::Variant. You correctly return an invalid Qt::Variant when the index
doesn't correspond to a valid data, but when you pick a value from
@string_list, you return the value as it is. From the name of the variable
(and also from the code in the Window's constructor) it's clear that the
contents of this instance variable are strings, not Qt::Variant, so you get
the error. The third line of the data method should be:

return Qt::Variant.new @string_list[index.row] if role == Qt.DisplayRole
|# def headerData section, orientation, role = Qt.DisplayRole
|# return Qt::Variant.new if role != Qt.DisplayRole
|#
|# if orientation == Qt.Horizontal
|# "Column #{section}"
|# else
|# "Row #{section}"
|# end
|# end
|end
|
|# window.rb
|require 'slmodel'
|
|class Window < Qt::Widget
| def initialize parent = nil
| super parent
|
| @list = %w[Alpha Beta Gamma Omega]
| @model = SLModel.new @list, self
| @view = Qt::ListView.new
|
| @view.setModel @model
|
| layout = Qt::VBoxLayout.new
| layout.addWidget @view
|
| setLayout layout
| end
|end
|
|# main.rb
|require 'Qt4'
|require 'window'
|
|a = Qt::Application.new ARGV
|window = Window.new
|window.show
|a.exec
|

By the way (in case you aren't already aware of this), qtruby allows you to
write code in a more rubysh way (rather than C++-ish). This means you can:
* use snake_case instead of camelCase from method names (for example,
layout.add_widget instead of layout.addWidget)
* use assignment instead of "setter" methods (but only for setter methods
taking one argument). For example, self.layout = layout instead of setLayout
layout

I hope this helps

Stefano
 
A

Arturo Bonechi

Thank you for the reply!
The problem with your code is that the #data method must always return a
Qt::Variant. You correctly return an invalid Qt::Variant when the index
doesn't correspond to a valid data, but when you pick a value from
@string_list, you return the value as it is. From the name of the
variable
(and also from the code in the Window's constructor) it's clear that the
contents of this instance variable are strings, not Qt::Variant, so you
get
the error. The third line of the data method should be:

return Qt::Variant.new @string_list[index.row] if role == Qt.DisplayRole

Indeed, it works!
So, I will be more careful with the C++ return type now.
By the way (in case you aren't already aware of this), qtruby allows you
to
write code in a more rubysh way (rather than C++-ish). This means you
can:
* use snake_case instead of camelCase from method names (for example,
layout.add_widget instead of layout.addWidget)
* use assignment instead of "setter" methods (but only for setter
methods
taking one argument). For example, self.layout = layout instead of
setLayout
layout

Yes, I'm aware of this, but since I'm a beginner both with Ruby and Qt,
I use CamelCase so that I know that is a Qt-method or Qt-attribute.
Maybe at some point, when I'll be comfortable enough with Qt, I'll
switch to "snake_case"...
I hope this helps

Yes, a lot! Thanks once again!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top