Class: ObjectTableModel

Inherits:
Qt::AbstractTableModel
  • Object
show all
Includes:
Enumerable, QtFlags
Defined in:
lib/qtext/object_table_model.rb

Overview

A specialisation of Qt::TableModel that is given a collection of objects, and a collection of headers, which are methods to call on the objects to populate columns.

Given

Thing = Struct.new( :name, :value, :location, :price, :other, :ignored )

and

@data = method_to_create_lots_of_things

The following will display the four named attributes in 4 columns

ObjectTableModel.new :data => @data, :headers => [ :name, :value, :location, :price ]

and this will right-align the price column:

ObjectTableModel.new :data => @data, :headers => [ :name, :value, :location, Header.new( :attribute => :price, :alignment => Qt::AlignRight ) ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from QtFlags

#const_as_string, #item_boolean_flags, #qt_aligncenter, #qt_alignleft, #qt_alignright, #qt_background_role, #qt_checked, #qt_checkstate_role, #qt_decoration_role, #qt_display_role, #qt_edit_role, #qt_font_role, #qt_foreground_role, #qt_item_is_editable, #qt_paste_role, #qt_size_hint_role, #qt_text_alignment_role, #qt_tooltip_role, #qt_unchecked

Constructor Details

#initialize(args = {}) ⇒ ObjectTableModel

args can contain the following:

  • :parent => the Qt::Object that is the parent of this class.

  • :headers => array of either symbols representing the attribute on the elements of the data collection, or Header instances.

  • :data => array of objects, with attributes corresponding to the headers

  • :collection is an alias for :data



81
82
83
84
85
86
# File 'lib/qtext/object_table_model.rb', line 81

def initialize( args = {} )
  super( args[:parent] )
  @parent = args[:parent]
  @collection = args[:data] || args[:collection] || []
  set_headers( args[:headers] )
end

Instance Attribute Details

#collectionObject

Returns the value of attribute collection.



63
64
65
# File 'lib/qtext/object_table_model.rb', line 63

def collection
  @collection
end

#headersObject

Returns the value of attribute headers.



63
64
65
# File 'lib/qtext/object_table_model.rb', line 63

def headers
  @headers
end

Instance Method Details

#<<(obj) ⇒ Object

Insert a new object into the collection, and make sure the view is updated.



238
239
240
241
242
# File 'lib/qtext/object_table_model.rb', line 238

def <<( obj )
  beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size )
  collection << obj
  endInsertRows
end

#[](index) ⇒ Object



221
222
223
# File 'lib/qtext/object_table_model.rb', line 221

def []( index )
  collection[index]
end

#[]=(index, value) ⇒ Object

Set the value at the index, and make sure the view is updated.



226
227
228
229
230
231
232
233
234
235
# File 'lib/qtext/object_table_model.rb', line 226

def []=( index, value )
  if index >= collection.size
    beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size + ( index - collection.size ) )
    collection[index] = value
    endInsertRows
  else
    collection[index] = value
    emit dataChanged( create_index( index.row, 0 ), create_index( index.row, columnCount ) )
  end
end

#clearObject



253
254
255
256
# File 'lib/qtext/object_table_model.rb', line 253

def clear
  collection.clear
  reset
end

#column_count(parent_index = Qt::ModelIndex.invalid) ⇒ Object

Rubyish method for columnCount



71
72
73
# File 'lib/qtext/object_table_model.rb', line 71

def column_count( parent_index = Qt::ModelIndex.invalid )
  columnCount( parent_index )
end

#columnCount(parent_model_index = Qt::ModelIndex.invalid) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/qtext/object_table_model.rb', line 97

def columnCount( parent_model_index = Qt::ModelIndex.invalid )
  if parent_model_index.valid?
    parent_model_index.entity.children.size == 0 ? 0 : headers.size
  else
    headers.size
  end
end

#data(index, role = qt_display_role) ⇒ Object

implementation of Qt:AbstractItemModel method



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/qtext/object_table_model.rb', line 146

def data( index, role = qt_display_role )
  return nil.to_variant unless index.valid?
  #~ puts "requesting data for index: #{index.inspect} and role: #{const_as_string role}"
  begin
    retval =
    case role
      when qt_display_role, qt_edit_role
        field_value_at( index )
       
      when qt_text_alignment_role
        headers[index.column].alignment
        
      when qt_checkstate_role
        #~ value = self[index.row].send( attribute_for_index( index.column ) )
        #~ value ? Qt::Checked : Qt::Unchecked
        
      # these are just here to make debug output quieter
      when qt_size_hint_role;
      when qt_background_role;
      when qt_font_role;
      when qt_foreground_role;
      when qt_decoration_role;
      
      when qt_tooltip_role;
        
      else
        puts "data index: #{index}, role: #{const_as_string(role)}" if $OPTIONS[:debug]
        nil
    end
      
    # return a variant
    retval.to_variant
  rescue Exception => e
    puts e.backtrace.join( "\n" )
    puts "#{index.inspect} #{e.message}"
    nil.to_variant
  end
end

#each(&block) ⇒ Object



245
246
247
# File 'lib/qtext/object_table_model.rb', line 245

def each( &block )
  collection.each( &block )
end

#flags(index) ⇒ Object

implementation of Qt:AbstractItemModel method – TODO make this editable



216
217
218
219
# File 'lib/qtext/object_table_model.rb', line 216

def flags( index )
  return 0 unless index.valid?
  super
end

#headerData(section, orientation, role) ⇒ Object

implementation of Qt:AbstractItemModel method



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/qtext/object_table_model.rb', line 119

def headerData( section, orientation, role )
  value =
  case orientation 
    when Qt::Vertical
      case role
        when qt_display_role
          ( section + 1 ).to_s
        
        when qt_text_alignment_role
          Qt::AlignVCenter | Qt::AlignRight
        
      end
    
    when Qt::Horizontal
      case role
        when qt_display_role
          headers[section].title
        
        when qt_text_alignment_role
          Qt::AlignVCenter | Qt::AlignCenter
        
      end
  end
  value.to_variant
end

#parent(*args) ⇒ Object

TODO what exactly is this for again? Something to do with QWidget.parent() and Qt::AbstractTableModel.parent(…)



107
108
109
110
111
112
113
114
115
116
# File 'lib/qtext/object_table_model.rb', line 107

def parent( *args )
  if args.size == 0
    retval = super()
    retval || @parent
  else
    if model_index.valid?
      collection.index( model_index.entity.parent )
    end
  end
end

#row_count(parent_index = Qt::ModelIndex.invalid) ⇒ Object

Rubyish method for rowCount



66
67
68
# File 'lib/qtext/object_table_model.rb', line 66

def row_count( parent_index = Qt::ModelIndex.invalid )
  rowCount( parent_index )
end

#rowCount(parent_model_index = Qt::ModelIndex.invalid) ⇒ Object

implementation of Qt:AbstractItemModel method



89
90
91
92
93
94
95
# File 'lib/qtext/object_table_model.rb', line 89

def rowCount( parent_model_index = Qt::ModelIndex.invalid )
  if parent_model_index.valid?
    parent_model_index.entity.children.size
  else
    collection.size
  end
end

#setData(index, variant, role = qt_edit_role) ⇒ Object

implementation of Qt:AbstractItemModel method



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/qtext/object_table_model.rb', line 186

def setData( index, variant, role = qt_edit_role )
  return false unless index.valid?
  begin
    item = self[index.row]
    method_name = attribute_for_index( index.column ).to_s
    value =
    case role
      when qt_edit_role
        variant.value
      when qt_checkstate_role
        case variant.value
          when Qt::Checked; true
          when Qt::Unchecked; false
          else; false
        end
    end
    
    # update UI
    emit dataChanged( index, index )
    
    # value conversion OK
    true
  rescue Exception => e
    puts e.message
    false
  end
end

#to_aObject



249
250
251
# File 'lib/qtext/object_table_model.rb', line 249

def to_a
  collection.dup
end