王朝网络
分享
 
 
 

Perl/TkFAQ-10.5.如何绑定键盘上的按键

王朝perl·作者佚名  2008-05-18
宽屏版  字体: |||超大  

原文:

10.5. How do I bind keyboard keys?

There are many default key bindings built in to the widgets of perl/Tk. Making proper use of them often involves setting up the right callback. (You may wish to consult the examples in BindTable.pod for help with this subject.)

The basic idea is:

$widget -> bind('<keyname>' => action);

Where $widget is the tag or ID of the widget for which the bindings are to hold (note for global bindings you have to bind to <All>, for semi-global bindings you need to bind to all the relevant widgets in your application), '<keyname>' can be things like:

<Key> or <KeyPress> or <Any-KeyPress>

<KeyRelease>

<Button> or <ButtonPress>

<ButtonRelease>

<Button-1> or <B1>

<Double-1>

<Enter>

<Leave>

<Motion>

To figure out what names perl/Tk uses for such <bindings> use the "binder-finder" on a widget's .pm file. For example, you could find bindings hidden inside of Button.pm by typing this at your shell prompt:

perl -ne 'print if s/.*(<[^>]*>).*/$1/g;' Button.pm

while in the directory where Button.pm is located (and if you are not there then simply specify the /path/to/Button.pm). Note that due to inheritance (e.g.the type of script bindings that are being discussed here) what the binder-finder turns up may not be the last word on a given widget's behaviour. This may be especially true for a widget inside of a compound/composite widget. Note also that the binder-finder will turn up things like <FILEHANDLES> as well as honest <Bindings>. Discrimination in its use is called for (and while your at it you could have just as easily used an editor and actually examined the code directly now couldn't you?).

To get an idea of what the code is for a key that you are interested in try running the xlib_demo that comes in your perl/Tk build directory. Hold your mouse pointer over the window that appears and simply type the key that you are interested in. The code should appear in the window. If you do not have perl/Tk up and running yet try "xmodmap -pk" or look directly at the /usr/include/X11/keysymdef.h file where keysym names are given with an XK_ pre-pended. Do not try things like the Tcl/Tk %k symbols in perl scripts. %Ks will be mis-interpreted as non-existant perl hashes. Instead look at the Xevent function.

Ali Corbin mailto:corbin@adsw.fteil.ca.boeing.com recently posted a great little script for determining keyboard key bindings on a MainWindow:

#!/usr/local/bin/perl -w

use Tk;

$top = MainWindow->new();

$frame = $top->Frame( -height => '6c', -width => '6c',

-background => 'black', -cursor => 'gobbler' );

$frame->pack;

$top->bind( '<Any-KeyPress>' => sub

{

my($c) = @_;

my $e = $c->XEvent;

my( $x, $y, $W, $K, $A ) = ( $e->x, $e->y, $e->K, $e->W, $e->A );

print "A key was pressed:\n";

print " x = $x\n";

print " y = $y\n";

print " W = $K\n";

print " K = $W\n";

print " A = $A\n";

} );

MainLoop();

To bind the action of one widget to that of another try taking a look at the .pm file for the widget of interest - is there a binding function already defined? If so you may use it. An example would be the use of "Up" & "Down" Buttons for a Listbox: one could bind the Buttons to call Tk::Listbox::UpDown, however, Guy Decoux describes a much more clever way to use the <Up> and <Down> already defined in Listbox.pm (this does not work with Tk-b9.01):

#!/usr/local/bin/perl

use Tk;

$top = MainWindow->new;

$lb = $top->Listbox(-height => 10);

for($i=0; $i < 120; $i++) {

$lb->insert('end', $i);

}

$f = $top->Frame;

$up = $f->Button(

-text => "Up",

-command => [ $lb->bind(ref $lb, '<Up>'), $lb]

);

$down = $f->Button(

-text => "Down",

-command =>sub {&{$lb->bind(ref $lb, '<Down>')}($lb)}

);

$up->pack(-side => 'left');

$down->pack;

$f->pack;

$lb->pack;

MainLoop;

译文:

10.5. 如何绑定键盘上的按键?

Perl/Tk有很多内置的按键绑定,但你需要适当的设定的回应函数才能正确的使用它们。(可以参考BindTable.pod中的例子)

最基本的用法如下:

$widget -> bind(‘<keyname>’=> action);

其中$widget是所要被设置绑定的组件的标签(tag)或ID(注:对于全局绑定,你必须设置绑定为<All>,而对于半全局的绑定,你则需要给所有你的应用程序中的相关组件设置绑定);‘<keyname>’可以是下面的任何一个:

<Key> 或 <KeyPress> 或 <Any-KeyPress>

<KeyRelease>

<Button> 或 <ButtonPress>

<ButtonRelease>

<Button-1> 或 <B1>

<Double-1>

<Enter>

<Leave>

<Motion>

要想知道某个组件的.pm文件中已经设定了哪些绑定,可以对它们使用“绑定搜索器”。例如,我们可以通过在命令行中键入下面的命令来找出Button.pm中隐藏的绑定:

perl -ne 'print if s/.*(<[^>]*>).*/$1/g;' Button.pm (译者注:在windows系统中需要把单撇号[']替换为双撇号["]才能使用)

上面的命令需要在Button.pm文件所在的目录中使用,否则你必须指定正确的路径。注意,由于继承性的缘故,我们给出的这个“绑定搜索器”所发现的结果可能不是某个给定的组件的所有绑定(例如这里我们讨论的绑定类型)。尤其是对于那些混合的或组合的组件。另外,请注意,这个“绑定搜索器”在发现真正的绑定的同时可能还会输出诸如<FILEHANDLES>这样的文件句柄读入语句。它们的区别就是后面是否有函数调用,所以你可以通过直接用文本编辑器实际的查看脚本代码来很容易的区分它们。

要想知道你所感兴趣的按键的具体代码是什么,可以运行你的Perl/Tk安装目录中的xlib_demo程序。把鼠标放在出现的窗口上,然后只要按下你所感兴趣的按键,它的代码就会显示在窗口中了。如果你还没有安装和运行Perl/Tk,可以尝试用“xmodmap -pk”命令或者直接查看/usr/include/X11/keysymdef.h文件。不要在Perl脚本中使用Tcl/Tk的%k符号,因为它将被误认为是一个没有定义的Perl的hash,而不是作为Xevent的函数。(译者注:以上都是针对Unix/Linux系统而言的,Windows系统用户可以用下面的脚本)

Ali Corbin最近贴出了一个非常有用而又小巧的脚本,可以查看键盘按键的绑定用代码:

#!/usr/local/bin/perl -w

use Tk;

$top = MainWindow->new();

$frame = $top->Frame( -height => '6c', -width => '6c',

-background => 'black', -cursor => 'gobbler' );

$frame->pack;

$top->bind( '<Any-KeyPress>' => sub

{

my($c) = @_;

my $e = $c->XEvent;

my( $x, $y, $W, $K, $A ) = ( $e->x, $e->y, $e->K, $e->W, $e->A );

print "A key was pressed:\n";

print " x = $x\n";

print " y = $y\n";

print " W = $K\n";

print " K = $W\n";

print " A = $A\n";

} );

MainLoop();

在给一个组件设置某种绑定之前,我们最好先看一下这个组件的.pm文件——看看它是否已经定义了某些绑定,如果是这样的话,就可以直接利用了。例如,要想在 Listbox组件中使用“Up”和“Down”的按钮,我们就可以设置绑定来调用Tk::Listbox::UpDown函数。然而,Guy Decoux给出了一种更加聪明的方法——直接使用在Listbox.pm中已经定义的<Up>和<Down>(Tk- b9.01不能运行):

#!/usr/local/bin/perl

use Tk;

$top = MainWindow->new;

$lb = $top->Listbox(-height => 10);

for($i=0; $i < 120; $i++) {

$lb->insert('end', $i);

}

$f = $top->Frame;

$up = $f->Button(

-text => "Up",

-command => [ $lb->bind(ref $lb, '<Up>'), $lb]

);

$down = $f->Button(

-text => "Down",

-command =>sub {&{$lb->bind(ref $lb, '<Down>')}($lb)}

);

$up->pack(-side => 'left');

$down->pack;

$f->pack;

$lb->pack;

MainLoop;

(译者注:实在不好意思,水平有限,上面的程序我没看明白,无论在Unix还是Windows系统上我都没有调试成功。无奈,我只能把它修改如下:

#!/usr/local/bin/perl

use Tk;

$top = MainWindow->new;

$lb = $top->Scrolled('Listbox',-scrollbars=>'e',-height => 10);

for($i=0; $i < 120; $i++) {

$lb->insert('end', $i);

}

$f = $top->Frame;

$top->bind('<Up>'=>sub{$lb->UpDown(-1);});

$top->bind('<Down>'=>sub{$lb->UpDown(1);});

$up = $f->Button(

-text => "Up",

-command => sub{$lb->UpDown(-1);}

);

$down = $f->Button(

-text => "Down",

-command =>sub{$lb->UpDown(1);}

);

$up->pack(-side => 'left');

$down->pack;

$f->pack;

$lb->pack;

MainLoop;

这样,应该可以运行,但是显然不是原著的本意。所以,还请哪位高手指教!)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有