2016-11-11 55 views
1

我有Gtk2 :: TreeView,一些列正在使用CellRendererCombo。我有一切工作正常,除了我无法获得CellRendererCombo中所选项目的整数索引。 不是文字,而是整数值
作为一种解决方法,将某种散列与combo_model关联起来可能会很有用,但我不知道如何。 有人可以帮我吗?尝试和谷歌搜索几天了。

下面的代码:Perl Gtk2 CellRendererCombo:获取所选项目索引

#!/usr/bin/perl 

package uform; 

use utf8; 
use warnings; 
use strict; 
use Gtk2 -init; 
use Glib qw/TRUE FALSE/; 
use Glib ':constants'; 
use Data::Dumper; 

use constant col0 => 0; 
use constant col1 => 1; 
use constant col2 => 2; 
use constant colC => 3; 

binmode(STDOUT,':utf8'); 

my $model; my $treeview; my @attr_models; 

sub create_window ($$) { 
    my ($width,$height)=(shift,shift); 
    my $window = Gtk2::Window->new("toplevel"); 
    $window->signal_connect("destroy", sub { Gtk2->main_quit(); }); 
    $window->set_default_size($width,$height); 

    my $vbox = Gtk2::VBox->new(0, 5); 

    $model = Gtk2::ListStore->new(
        "Gtk2::Gdk::Pixbuf", #0 pic 
        "Glib::String", #1 product 
        "Glib::String", #2 attr 
        "Gtk2::ListStore" #combo values list 
       ); 



    #sample_data 
    #some combo lists 
    foreach my $d (
    [qw(fast medium slow)], 
    [qw(greay orange black white rainbow)], 
    [qw(fat with_wholes molded)], 
    [qw(long short jeans)] 
    ) 
    { 
    my $cmodel = Gtk2::ListStore->new('Glib::String'); 
    foreach my $str (@$d) {$cmodel->set($cmodel->append,0,$str);} 
    push @attr_models,$cmodel; 
    } 

    #some pixbufs to play with 
    my $pixbuf2 = Gtk2::Button->new->render_icon ('gtk-info', 'large-toolbar'); 



    #add some rows 
    my @data = (
    [$pixbuf2,'Shirt',1,$attr_models[0]], 
    [$pixbuf2,'Pants',0,$attr_models[0]], 
    [$pixbuf2,'Cheese',2,$attr_models[1]], 
    [$pixbuf2,'Cola',1,$attr_models[2]], 
    [$pixbuf2,'Laptop',0,$attr_models[3]] 
    ); 

    foreach my $st(@data) { 
    $st->[2]=$st->[3]->get($st->[3]->iter_nth_child(undef,$st->[2]), 0); 
     $model->set($model->append, 
     0, $st->[0], 
     1, $st->[1], 
     2, $st->[2], 
     3, $st->[3], 
    ); 
    } 


#Column0 setup 
my $combo_model0 = Gtk2::ListStore->new('Gtk2::Gdk::Pixbuf'); 
my $renderer_0 = Gtk2::CellRendererPixbuf->new; 

my $column_0 = Gtk2::TreeViewColumn->new_with_attributes(
      "Pic", 
      $renderer_0, 
      pixbuf => col0 
      ); 



#Column1 setup 
my $renderer_1 = Gtk2::CellRendererText->new; 
$renderer_1->set(editable => FALSE); 

my $column_1 = Gtk2::TreeViewColumn->new_with_attributes(
      "Product", 
      $renderer_1, 
      text => col1 
      ); 




#Column2 setup 
my $renderer_2 = Gtk2::CellRendererCombo->new; 
$renderer_2->set(
      editable => TRUE, 
      text_column => 0, 
      has_entry => FALSE 
     ); 

$renderer_2->signal_connect (changed => sub { 
    my ($renderer, $str, $iter)[email protected]_; 
    print Dumper (@_) . "\n"; 
    } 
); 

$renderer_2->signal_connect (edited => 
    sub { 
    my ($renderer, $text_path, $new_text) = @_; 
     my $combo_model = $renderer->get("model"); 
    $model->set ($model->get_iter_from_string ($text_path), col2, $new_text); 
    } 
); 

my $column_2 = Gtk2::TreeViewColumn->new_with_attributes(
      "Attr", 
      $renderer_2, 
      text => col2, 
      model => colC 
      ); 







# main program starts 
$treeview = Gtk2::TreeView->new($model); 

$treeview->get_selection->set_mode ('single'); 
$treeview->set_rules_hint(TRUE); 

$treeview->append_column($column_0); 
$treeview->append_column($column_1); 
$treeview->append_column($column_2); 


my $sw = Gtk2::ScrolledWindow->new(undef, undef); 
$sw->set_shadow_type("etched-in"); 
$sw->set_policy("never", "always"); 

$sw->add($treeview); 

$vbox->pack_start($sw, 1, 1, 0); 

$window->add($vbox); 
$window->show_all; 
} 
+0

我不知道我的理解。你是否希望在'$ renderer_2'组合单元格渲染器的'edited'的回调中将'$ new_text'转换为表示其在选择列表中的垂直位置的索引?你为什么需要这个功能? –

+0

我想更喜欢“获取当前项目的索引”的定义,但是,是的,你是对的。 – berrymorr

+0

我需要这个,因为即使字符串是可接受的方式来识别一些列表的元素(例如哈希),这个字符串是可见的用户。这不是个好主意:你会显示格式不错的信息,或者没有搜索垂直索引的麻烦。但不是全部同时。 奇怪的是,我需要从CellRenderer继承我自己的子类,甚至使用ComboBox来获得一个整数。 另外,如果某些字符串不是唯一的,我害怕搜索精确索引时遇到很多麻烦。 – berrymorr

回答

1

所以,貌似没有这个问题的任何直接的答案。 作为解决方法,您可以创建散列数组。每个元素对应于一个TreeView的行,并且具有例如字段如'combo_hash''current_index'
“CURRENT_INDEX”是自解释的,“combo_hash”是阵列由具有像“文本”的某些字段散列和例如'索引'(或其他ID)。
在CellRendererCombo的'edited'信号你通过$treeview->get_selection()->get_selected_rows()->get_indices()当前TreeView的指数(这很简单INT),并通过“combo_hash”数组中CellRendererCombo的'text'字段中选择搜索。不要忘记存储发现'索引''current_index'
此替代方法允许不同TreeView行中的非唯一文本,但无法处理一个CellRendererCombo的ListStore中的非唯一文本。
另一个解决方法是从CellRenderer继承子类并嵌入ComboBox,它提供简单的整数索引。看起来更好,并且不受非唯一数据的限制,但如果设计中不可避免地存在散列数组(您需要存储很多其他信息(在TreeView中不可见),则第一种解决方法应该更加相关。