我使用Curses :: UI :: Grid来显示表格数据。该窗口由一个表和几个按钮组成,用于将数据显示窗口导航到其他窗口,如下所示:
然而,当显示数据时,焦点转到第一行,如果我使用选项卡将焦点转移到下一个UI控件,它永远不会转到底部的按钮。它只是循环通过第一行的单元格。
以下是重现问题的代码:
#!/usr/bin/env perl
use strict;
use warnings;
use Curses::UI;
use Curses::UI::Grid;
my $debug = 0;
# Create the root object.
my $cui = new Curses::UI (
-color_support => 1,
-clear_on_exit => 1,
-debug => $debug,
);
create_promote_deps_window();
$cui->set_binding( \&exit_dialog , "\cQ");
$cui->mainloop();
sub exit_dialog {
my $return = $cui->dialog(
-message => "Do you really want to quit?",
-title => "Confirm",
-buttons => ['yes', 'no'],
);
exit(0) if $return;
}
sub create_base_window {
my ($name) = @_;
$cui->add(
$name,
'Window',
-border => 1,
-titlereverse => 0,
-padtop => 2,
-padbottom => 3,
-ipad => 1,
-title => 'CTRL-Q to quiz',
);
}
sub create_promote_deps_window {
my ($name) = @_;
my $win = create_base_window($name);
my $grid = $win->add(
'grid',
'Grid',
-height => 14,
-width => -1,
-editable => 0,
-border => 1,
-process_bindings => {
CUI_TAB => undef,
},
# -bg => "blue",
# -fg => "white",
);
$grid->add_cell(
"otp",
-width => 10,
-label => "OTP"
);
$grid->add_cell(
"commit1",
-width => 10,
-label => "Commit#"
);
$grid->add_cell(
"otnp",
-width => 10,
-label => "OTNP"
);
$grid->add_cell(
"commit2",
-width => 10,
-label => "Commit#"
);
$grid->add_cell(
"overlap",
-width => 32,
-label => "Overlap"
);
my $button_callback = sub {
my $this = shift;
my $btn_name = $this->get();
if ($btn_name eq "Back") {
# give up promotion and return to promote window
$win->focus();
}
elsif ($btn_name eq "PromoteWithDeps") {
}
};
$win->add(
undef,
'Buttonbox',
-y => -1,
-buttons => [
{
-label => "< Back >",
-value => "Back",
-onpress => $button_callback,
},
{
-label => "< Promote w/ all deps >",
-value => "PromoteWithDeps",
-onpress => $button_callback,
},
],
);
my @data = (
['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/b.p'],
['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/a.p'],
['HDT-10', 'e3042b0', 'HDT-7', '6741e47', 'src/tc/c.p'],
['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/c.p'],
['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/b.p'],
['HDT-10', 'e3042b0', 'HDT-7', '66a3254', 'src/tc/a.p'],
['HDT-10', 'e3042b0', 'HDT-8', '8b65677', 'src/tc/e.p'],
['HDT-10', 'e3042b0', 'HDT-8', '8b65677', 'src/tc/d.p'],
['HDT-10', 'e3042b0', 'HDT-9', '3eefa90', 'src/tc/f.p'],
);
foreach my $f (@data) {
$grid->add_row(
undef,
# -fg => 'black',
# -bg => 'yellow',
-cells => {
otp => $f->[0],
commit1 => $f->[1],
otnp => $f->[2],
commit2 => $f->[3],
overlap => $f->[4],
}
);
}
$grid->layout();
return $win;
}
如何自定义Tab键顺序,以便用户可以将焦点移动到Curses :: UI :: Grid下面的按钮?
谢谢!
答案 0 :(得分:1)
你遇到网格标签的困难不在于窗口的标签排序,而在于Curses :: UI :: Grid为Tab和Shift +提供了自己的绑定标签。一个基本的解决方案是在网格具有焦点时按下Tab和Shift + Tab时提供自己的处理程序:
sub move_focus {
my $widget = $_[0];
my $key = $_[1];
if ($key eq "\t") {
$widget->parent()->focus_next();
}
else {
$widget->parent()->focus_prev();
}
}
然后,您可以将此处理程序绑定到网格:
$grid->set_binding(\&move_focus, "\t");
$grid->set_binding(\&move_focus, KEY_BTAB());
但是,您可能会发现使用光标键在单元格之间移动是单调乏味的,因此您可能仍希望能够在单元格之间进行制表,并且只有当光标位于行尾时才跳转到按钮。在这种情况下,您的自定义处理程序需要更加智能化:
sub move_focus {
my $grid = $_[0];
my $key = $_[1];
if ($key eq "\t") {
my $last_cell = $grid->get_cell($grid->{_cells}[$#{$grid->{_cells}}]);
if ($grid->get_foused_cell() == $last_cell) {
$grid->parent()->focus_next();
}
else {
$grid->next_cell();
}
}
else {
my $first_cell = $grid->get_cell($grid->{_cells}[0]);
if ($grid->get_foused_cell() == $first_cell) {
$grid->parent()->focus_prev();
}
else {
$grid->prev_cell();
}
}
}