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

> |#  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