Perl 已捕获诅咒::UI::网格选项卡

Perl 已捕获诅咒::UI::网格选项卡,perl,curses,Perl,Curses,我使用Curses::UI::Grid来显示表格数据。该窗口由一个表和几个按钮组成,用于将数据显示窗口导航到其他窗口,如下图所示: 但是,当显示数据时,焦点会移到第一行,如果我使用选项卡将焦点移到下一个UI控件,它永远不会移到底部的按钮。它只是循环通过第一行的单元格 下面是重现问题的代码: #!/usr/bin/env perl use strict; use warnings; use Curses::UI; use Curses::UI::Grid; my $debug = 0; #

我使用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;
}
#/usr/bin/env perl
严格使用;
使用警告;
使用诅咒::UI;
使用诅咒::UI::Grid;
我的$debug=0;
#创建根对象。
my$cui=新诅咒::UI(
-颜色支持=>1,
-在_退出时清除_=>1,
-调试=>$debug,
);
创建_promote_deps_window();
$cui->设置绑定(\&退出对话框,“\cQ”);
$cui->mainloop();
子退出对话框{
my$return=$cui->对话框(
-message=>“您真的想退出吗?”,
-title=>“确认”,
-按钮=>[“是”、“否”],
);
如果$return,则退出(0);
}
子创建基础窗口{
我的($name)=@;
$cui->添加(
$name,
“窗口”,
-边框=>1,
-titlereverse=>0,
-焊盘=>2,
-焊盘底部=>3,
-ipad=>1,
-title=>“按CTRL-Q键进行测验”,
);
}
子创建\升级\部门\窗口{
我的($name)=@;
my$win=创建基本窗口($name);
my$grid=$win->add(
“网格”,
“网格”,
-高度=>14,
-宽度=>-1,
-可编辑=>0,
-边框=>1,
-进程绑定=>{
CUI_选项卡=>未定义,
},
#-bg=>“蓝色”,
#-fg=>“白色”,
);
$grid->添加单元格(
“检察官办公室”,
-宽度=>10,
-标签=>“OTP”
);
$grid->添加单元格(
“委员会1”,
-宽度=>10,
-label=>“提交#”
);
$grid->添加单元格(
“otnp”,
-宽度=>10,
-标签=>“OTNP”
);
$grid->添加单元格(
“委员会2”,
-宽度=>10,
-label=>“提交#”
);
$grid->添加单元格(
“重叠”,
-宽度=>32,
-标签=>“重叠”
);
我的$button\u callback=sub{
我的$this=shift;
我的$btn_name=$this->get();
如果($btn_name eq“Back”){
#放弃促销并返回促销窗口
$win->focus();
}
elsif($btn_name eq“PromoteWithDeps”){
}
};
$win->add(
未定义,
“按钮盒”,
-y=>-1,
-按钮=>[
{
-label=>“”,
-值=>“返回”,
-onpress=>$button\u回调,
},
{
-label=>“”,
-值=>“PromoteWithDeps”,
-onpress=>$button\u回调,
},
],
);
我的@数据=(
[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->添加行(
未定义,
#-fg=>“黑色”,
#-bg=>“黄色”,
-单元格=>{
otp=>$f->[0],
佣金1=>$f->[1],
otnp=>$f->[2],
佣金2=>$f->[3],
重叠=>$f->[4],
}
);
}
$grid->layout();
返回$win;
}
如何自定义选项卡顺序,以便用户可以将焦点转移到Curses::UI::Grid下面的按钮


谢谢

将选项卡移出网格时遇到的困难不在于窗口的选项卡顺序,而在于Curses::UI::grid为tab和Shift+tab提供了自己的绑定。一个基本的解决方案是在网格具有焦点时,为按下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());
但是,您可能会发现使用光标键在单元格之间移动是一件乏味的事情,因此您可能仍然希望能够在单元格之间进行tab操作,并且只在光标位于行的末尾时跳转到按钮。在这种情况下,您的自定义处理程序需要更加智能:

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();
        }
    }
}