Perl Gtk2 CellRendererCombo:获取选定项索引
Perl Gtk2 CellRendererCombo: get selected item index
我有 Gtk2::TreeView,一些列正在使用 CellRendererCombo。我一切正常,除了我无法在 CellRendererCombo 中获取所选项目的整数索引。 不是文本,而是整数值。
作为一种解决方法,以某种方式将散列与 combo_model 相关联可能很有用,但我不知道该怎么做。
有人可以帮帮我吗?已经尝试和谷歌搜索了几天。
这是代码:
#!/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)=@_;
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;
}
看来这个问题没有任何直接的答案。
作为 解决方法 ,您可以创建散列数组。每个元素对应一个 TreeView 的行,例如'combo_hash' 和 'current_index'.
等字段
'current_index' 是不言自明的,'combo_hash' 是由散列和一些字段组成的数组,例如 'text' 例如'index'(或其他id)。
在 CellRendererCombo 的 'edited'
信号上,您通过 $treeview->get_selection()->get_selected_rows()->get_indices()
获取当前 TreeView 的索引(它是简单的整数),并通过 'combo_hash'[= 在 CellRendererCombo 的 'text'
字段中搜索 selected 31=]数组。不要忘记将找到的 'index' 存储到 'current_index'.
此解决方法允许不同 TreeView 行中的非唯一文本,但无法处理一个 CellRendererCombo 的 ListStore 中的非唯一文本。
另一种解决方法是从CellRenderer 继承子类并嵌入ComboBox,它提供简单的整数索引。看起来更好并且不受非唯一数据的限制,但如果哈希数组是设计不可避免的(您需要存储许多在 TreeView 中不可见的其他信息),第一个解决方法应该更相关。
我有 Gtk2::TreeView,一些列正在使用 CellRendererCombo。我一切正常,除了我无法在 CellRendererCombo 中获取所选项目的整数索引。 不是文本,而是整数值。
作为一种解决方法,以某种方式将散列与 combo_model 相关联可能很有用,但我不知道该怎么做。
有人可以帮帮我吗?已经尝试和谷歌搜索了几天。
这是代码:
#!/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)=@_;
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;
}
看来这个问题没有任何直接的答案。
作为 解决方法 ,您可以创建散列数组。每个元素对应一个 TreeView 的行,例如'combo_hash' 和 'current_index'.
等字段
'current_index' 是不言自明的,'combo_hash' 是由散列和一些字段组成的数组,例如 'text' 例如'index'(或其他id)。
在 CellRendererCombo 的 'edited'
信号上,您通过 $treeview->get_selection()->get_selected_rows()->get_indices()
获取当前 TreeView 的索引(它是简单的整数),并通过 'combo_hash'[= 在 CellRendererCombo 的 'text'
字段中搜索 selected 31=]数组。不要忘记将找到的 'index' 存储到 'current_index'.
此解决方法允许不同 TreeView 行中的非唯一文本,但无法处理一个 CellRendererCombo 的 ListStore 中的非唯一文本。
另一种解决方法是从CellRenderer 继承子类并嵌入ComboBox,它提供简单的整数索引。看起来更好并且不受非唯一数据的限制,但如果哈希数组是设计不可避免的(您需要存储许多在 TreeView 中不可见的其他信息),第一个解决方法应该更相关。