我在使文本验证正常工作时遇到问题。基本上我有2个输入框,一个用于输入CVS中的分支名称,另一个用于输入目录名称。我希望我的程序在每次更改时验证每个框中的文本。
为此,documentation online表示要使用"键"每当按键改变输入框的内容时验证条目的选项。问题是,当我使用"键"选项然后运行程序,当我在输入框中键入时,不会出现任何文本。
我的代码如下所示:
use strict;
use warnings;
use Tkx;
# Initialize BRANCH and DIRECTORY
my ($BRANCH, $DIRECTORY) = ();
# DEFINE DISPLAY OBJECTS ###########################################################################
# Define main window
my $main_window = Tkx::widget->new('.');
# Define content frame
my $content_frame = $main_window->new_ttk__frame(-padding => '5 5 5 5');
# Define labels
my $branch_label = $content_frame->new_ttk__label(-text => 'Branch' );
my $directory_label = $content_frame->new_ttk__label(-text => 'Directory');
# Define entry boxes
my $branch_entry = $content_frame->new_ttk__entry(-width => 20, -textvariable => \$BRANCH , -validate => 'key', -validatecommand => \&check_state);
my $directory_entry = $content_frame->new_ttk__entry(-width => 20, -textvariable => \$DIRECTORY, -validate => 'key', -validatecommand => \&check_state);
# Define buttons
my $generate_list_button = $content_frame->new_ttk__button(-text => 'Generate', -state => 'disabled', -command => \&generate_list);
# POSITION DISPLAY OBJECTS #########################################################################
# Position content frame
$content_frame->g_grid(-column => 0, -row => 0);
# Position labels
$branch_label ->g_grid(-column => 0, -row => 0);
$directory_label->g_grid(-column => 0, -row => 1);
# Position entry boxes
$branch_entry ->g_grid(-column => 1, -row => 0);
$directory_entry->g_grid(-column => 1, -row => 1);
# Position buttons
$generate_list_button->g_grid(-column => 0, -row => 2, -columnspan => 2);
# Add padding
for my $child (Tkx::SplitList($content_frame->g_winfo_children)) {
Tkx::grid_configure($child, -padx => 5, -pady => 5);
}
# Check the state of the program
sub check_state {
# Check conditions are met to enable generate_list
if ($BRANCH && $DIRECTORY) {
if (-d $DIRECTORY) {
$generate_list_button->state('!disabled');
} else {
$generate_list_button->state('disabled');
}
} else {
$generate_list_button->state('disabled');
}
return 0;
}
Tkx::MainLoop();
如果我改变"键"它可以正常工作(如聚焦)。但我真的希望它能在每次击键后进行验证,而不仅仅是当焦点从输入框中取出时。为什么这不起作用?
答案 0 :(得分:2)
您的check_state
子程序始终返回0,表示“验证失败”并阻止
输入的文字。由于您没有真正验证文本 - 只是使用验证机制来触发相关小部件的状态更新 - 您应该返回1(无条件)。有关详细信息,请参阅(Tcl)Tk文档中的validatecommand。
答案 1 :(得分:2)
返回0的子程序只是问题的一半。一旦我修复了条目验证没有正常运作。发生的事情是,每当它试图验证它实际上将验证前一个条目的条目时。
例如:
如果您键入“/ somedirectory”,它会尝试在每次击键时进行验证,在“y”的最后一次击键后,它将获得$DIRECTORY
的值并对其进行验证。问题是此时$DIRECTORY
将等于“/ somedirector”
要解决这个问题,我不得不做一些挖掘,所以我想发布我的发现,以防其他人遇到同样的问题。
解决方案是使用Tkx::Ev()
来获取输入条目时的“当前”值。
(Tkx :: Ev(%P)获取新输入的值,以便验证正常运行)
# Define the entry box
my $directory_entry = $content_frame->new_ttk__entry(
-width => 20,
-textvariable => \$DIRECTORY,
-validate => 'key',
-validatecommand => [\&check_dir, Tkx::Ev('%P')],
);
# Validate the entry box
sub check_dir {
# Unpack input arguments
my ($P) = @_;
if (-d $P) {
# Do something here
} else {
# Do something else here
}
return 1;
}