Re: custom TreeModel




On Aug 21, 2005, at 7:44 AM, Jens Luedicke wrote:

I whipped up a custom TreeModel and I get the following error:

type Filer::ListStore does not support property 'Glib::Object' at
/home/jens/devel/filer/Filer/FilePane.pm line 100.

My custom TreeModel has 7 columns:

$treemodel{ident $self} = new Filer::ListStore(qw(Glib::Object
Glib::String Glib::String Glib::String Glib::String Glib::String
Glib::Scalar));

any idea how to fix this?

Short answer:

Either

  # set the column types in instance initializer.  handy for
  # future derivation, but not so handy if you wanted the
  # column types to be set by a subclass.
  sub INIT_INSTANCE {
      my $self = shift;
      # where set_column_types is a method of your own that
      # tells your instance what the column types are.  it doesn't
      # have to be like this, it could just be an array assignment.
      $self->set_column_types (qw(Glib::Object Glib::String...));
  }

or

  # parameterized constructor.
  sub new {
      my ($class, @column_types) = @_;
      my $self = Glib::Object::new ($type);
      # see note above about set_column_types
      $self->set_column_types (@_);
      return $self;
  }


Long answer:

You're inheriting Glib::Object::new(), which treats the argument list as property-name/value pairs. However, you're trying to call it like Gtk2::ListStore::new, which takes a list of column types that are then passed to gtk_list_store_set_column_types().

The TreeModel GInterface provides an API for querying and using a TreeModel; each implementation is responsible for coming up with its own way to configure and populate the store.

Glib::Object::Subclass checks to see if your class has a new(); if it doesn't, it will alias YourClass::new() to Glib::Object::new(), which is a factory constructor. This is important, because the factory constructor is the only way to create a GObject instance; the various widget and object constructors in each class of gtk+'s API are actually convenience functions which merely marshal their parameters into g_object_new(). To ensure useful derivation, pretty much everything that you can configure about a GObject should be made an object property, and no setup code should occur in a new() implementation.

For your Filer::ListStore, the first question is, "is this supposed to be a special-case store object, or a parameterized store?" That is, will you want to create a Filer::ListStore with different column types in different parts of your code? If the answer is "no", then set up your column types in INIT_INSTANCE so that no matter how the object gets created, the column types will be right. If the answer is "yes", you'll need to provide some way to set the column types after the object has been instantiated. Gtk2::ListStore provides set_column_types() for exactly this purpose.

You can, of course, mix and match these approaches. For example, Filer::ListStore may be a parameterized list, but Filer::FooList may set the column types in its INIT_INSTANCE so that creating one is as simple as "$foolist = Filer::FooList->new($where_to_find_the_foos);".


--
muppet <scott at asofyet dot org>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]