2016-11-11 102 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中不可見),則第一種解決方法應該更加相關。