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



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

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.



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

def collection
  @collection
end

#headersObject

Returns the value of attribute headers.



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

def headers
  @headers
end

Instance Method Details

#<<(obj) ⇒ Object

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



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

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

#[](index) ⇒ Object



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

def []( index )
  collection[index]
end

#[]=(index, value) ⇒ Object

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



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

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



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

def clear
  collection.clear
  reset
end

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

Rubyish method for columnCount



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

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

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



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

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



145
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
# File 'lib/qtext/object_table_model.rb', line 145

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



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

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

#flags(index) ⇒ Object

implementation of Qt:AbstractItemModel method – TODO make this editable



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

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

#headerData(section, orientation, role) ⇒ Object

implementation of Qt:AbstractItemModel method



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

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(…)



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

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



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

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



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

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



185
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
# File 'lib/qtext/object_table_model.rb', line 185

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



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

def to_a
  collection.dup
end