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
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?
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”…
On Sunday 05 September 2010, Arturo Bonechi wrote:
|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
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
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.