Re: show different value to actual value in combobox - is this possible



On Tue, 17 Mar 2009 17:07:14 +0000, Mike Martin <redtux1 googlemail com>
wrote:

Basically my question is :

In msaccess you can have a query linked to a combox with two or more
values, with the first being the data value and the second being for
presentation
You can have the "presentation" value appear in the combobox by hiding
the first column, but the first column is still the value that the
combobox is based on.

Is this possible in Gtk2

Sure is :)

You have to create a Gtk2::ListStore and pack it with key / value pairs,
then attach it to your Gtk2::ComboBoxEntry. Here is a copy & paste from my
Gtk2::Ex::DBI project ( which you may be interested in if you're doing
database stuff, by the way ):

    # Support using an SQL select string *instead* of an array of field
definitions
    if ( exists $combo->{sql}->{select} && ! exists $combo->{fields} ) {
        
        # In this case, we clobber whatever was in the array of field
definitions
        # ( if there was anything ) and construct our own ...
        
        $combo->{fields} = ();
        
        #  ... and screw supporing aliases and other stuff
        my @fields = split /\,/, $combo->{sql}->{select};
        
        foreach my $field ( @fields ) {
            push @{$combo->{fields}},
                {
                    name    => $field,
                    type    => "Glib::String" # TODO Detect type from
database? Factor out detection from constructor?
                };
        }
        
    }

Above, I'm looping through fields in the select string, and building an
array ( $combo->{fields} ) of hashes. The 'type' ( Glib::String ) is later
appended to another array ( @liststore_def ), which tells Gtk2 about the
number and type of columns. So basically I'm using a Glib::String column
for each item in the select string.

A bit later, I do something like ( lots of other stuff cut out ):

    foreach my $field ( @{$combo->{fields}} ) {
        push @liststore_def, $field->{type}; # TODO automatically select
type based on column_info from DB server
    }

 ... and then later still:

    # Create the model
    my $model = Gtk2::ListStore->new( @liststore_def );
    
    while ( my @row = $sth->fetchrow_array ) {
        
        # We use fetchrow_array instead of fetchrow_hashref so
        # we can support the use of aliases in the fields
        
        my @model_row;
        my $column = 0;
        push @model_row, $model->append;
        
        foreach my $field ( @{$combo->{fields}} ) {
            push @model_row, $column, $row[$column];
            $column ++;
        }
        
        $model->set( @model_row );
        
    }
    
    $sth->finish;
    $local_dbh->disconnect;
    
    # Connect the model to the widget
    $widget->set_model( $model );

At this point, the Gtk2::ComboBoxEntry is *basically* connected, but there
are some caveats :( There is currently a long-standing bug in Gtk2
ComboBoxEntry ( the C library, not the Perl binding ) which means that if
someone types something in the entry portion of the widget, *no* attempt is
made to match the text they typed with the text in your model. So if you
try to fetch the primary key value from the combo, you'll get *nothing* (
ie no match ). I've worked around this in Gtk2::Ex::DBI :) You have to
connect to the focus-out event of the entry portion of the widget, and
manually walk through the list of values in the model, and if you find a
match, manually set the combo to the correct value. For more info, see:
http://bugzilla.gnome.org/show_bug.cgi?id=156017 - I submitted a patch for
this, but it's no good ... it causes crashes in some cases for me. I made
this patch *ages* ago, before I really knew what I was doing. I've since
learned a *bit* more C, and will return to fix it and push again for
integrating it into Gtk2 ( time permitting ). Anyway, for the full
workaround, you can look at Gtk2::Ex::DBI's
set_active_iter_for_broken_combo_box method.

For more cool database stuff ( yeah I just keep plugging ... ), see
http://entropy.homelinux.org/axis/

Also I'm looking for help / motivation to finish of a GUI builder for the
above project. We have a 7-month-old boy now, and he's consuming all my
free time, so the project has pretty much stalled at the moment ( but is in
production use and extremely thoroughly tested ).

Dan



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