以下是一个简单的编程项目,能够帮助你开始学习 Tcl/Tk。
探索 Tcl/Tk 的基础构造,包括用户输入、输出、变量、条件评估、简单函数和基础事件驱动编程。
我写这篇文章的初衷源于我想更深入地利用基于 Tcl 的 Expect。这让我写下了以下两篇文章:通过编写一个简单的游戏学习 Tcl和通过编写一个简单的游戏学习 Expect。
我进行了一些 Ansible自动化工作,逐渐积累了一些本地脚本。有些脚本我频繁使用,以至于以下循环操作变得有些烦人:
打开终端使用 cd命令跳转至合适的目录输入一条带有若干选项的长命令启动所需的自动化流程我日常使用的是 macOS。实际上我更希望有一个菜单项或者一个图标,能够弹出一个简单的界面接受参数并执行我需要的操作,这就像在 Linux 的 KDE 中一样。
经典的 Tcl 类书籍都包含了关于流行的 Tk 扩展的文档。既然我已经深入研究了这个主题,我尝试着对其(即 wish)进行编程。
虽然我并非一名 GUI 或者前端开发者,但我发现 Tcl/Tk 脚本编写的方式相当直接易懂。我很高兴能重新审视这个 UNIX 历史的古老且稳定的部分,这种技术在现代平台上依然有用且可用。
安装 Tcl/Tk对于 Linux 系统,你可以按照下面的方式安装:
$ sudo dnf install tcl$ which wish/bin/wish
而在 macOS 上,你可以通过 Homebrew来安装最新版的 Tcl/Tk:
$ brew install tcl-tk$ which wish/usr/local/bin/wish
编程理念许多编写游戏的教程都会介绍到典型的编程语言结构,如循环、条件判断、变量、函数和过程等等。
在此篇文章中,我想要介绍的是 事件驱动编程。当你的程序使用事件驱动编程,它会进入一个特殊的内置循环,等待特定的事件发生。当这个特定的事件发生时,相应的代码就会被触发,产生预期的结果。
这些事件可以包括键盘输入、鼠标移动、点击按钮、定时器触发,甚至是任何你的电脑硬件能够识别的事件(可能来自特殊的设备)。你的程序中的代码决定了用户看到了什么,以及程序需要监听什么输入,当这些输入被接收后程序会怎么做,然后进入事件循环等待输入。
这篇文章的理念并没有脱离我之前的 Tcl 文章太远。这里最大的不同在于用 GUI 设置和用于处理用户输入的事件循环替代了循环结构。其他的不同则是 GUI 开发需要采取的各种方式来制作一个可用的用户界面。在采用 Tk GUI 开发的时候,你需要了解两个基础的概念:部件widget和几何管理器geometry manager。
部件是构成可视化元素的 UI 元素,通过这些元素用户可以与程序进行交互。这其中包括了按钮、文本区域、标签和文本输入框。部件还包括了一些选项选择,如菜单、复选框、单选按钮等。最后,部件也包括了其他的可视化元素,如边框和线性分隔符。
几何管理器在放置部件在显示窗口中的位置上扮演着至关重要的角色。有一些不同的几何管理器可以供你使用。在这篇文章中,我主要使用了 grid几何来让部件在整齐的行中进行布局。我会在这篇文章的结尾地方解释一些几何管理器的不同之处。
用 wish 进行猜数字游戏这个示例游戏代码与我其他文章中的示例有所不同,我将它分解为若干部分以方便解释。
首先创建一个基本的可执行脚本 numgame.wish:
$ touch numgame.wish$ chmod 755 numgame.wish
使用你喜欢的文本编辑器打开此文件,输入下列代码的第一部分:
#!/usr/bin/env wishset LOW 1set HIGH 100set STATUS \"\"set GUESS \"\"set num [expr round(rand()*100)]
第一行定义了该脚本将通过 wish执行。接下来,创建了几个全局变量。这里我使用全部大写字母定义全局变量,这些变量将绑定到跟踪这些值的窗口小部件(LOW、HIGH等等)。
全局变量 num是游戏玩家要猜测的随机数值,这个值是通过 Tcl 的命令执行得到并保存到变量中的:
proc Validate {var} { if { [string is integer $var] } { return 1 } return 0}
这是一个验证用户输入的特殊函数,它只接受整数并拒绝其他所有类型的输入:
proc check_guess {guess num} { global STATUS LOW HIGH GUESS if { $guess $HIGH } { set STATUS \"Huh?\" } elseif { $guess $num } { set STATUS \"Too high!\" set HIGH $guess } else { set LOW $guess set HIGH $guess set STATUS \"That's Right!\" destroy .guess .entry bind all
这是主要的猜数逻辑循环。global语句让我们能够修改在文件开头创建的全局变量(关于此主题后面将会有更多解释)。这个条件判断寻找入力范围在 1 至 100 之外以及已经被用户猜过的值。有效的猜测和随机值进行比较。LOW和HIGH的猜测会被追踪,作为 UI 中的全局变量进行报告。在每一步,全局STATUS变量都会被更新,这个状态信息会自动在 UI 中显示。
对于正确的猜测,destroy语句会移除 “Guess” 按钮以及输入窗口,并重新绑定回车键,以激活 “Quit” 按钮。
最后的语句 set GUESS \"\"用于在下一个猜测之前清空输入窗口。
label st -text \"Enter a number between: \"label .low -textvariable LOWlabel .dash -text \"-\"label .high -textvariable HIGHlabel .status -text \"Status:\"label .result -textvariable STATUSbutton .guess -text \"Guess\" -command { check_guess $GUESS $num }entry .entry -width 3 -relief sunken -bd 2 -textvariable GUESS -validate all \ -validatecommand { Validate %P }focus .entrybutton .quit -text \"Quit\" -command { exit }bind all
这是设置用户界面的部分。前六个标签语句在你的 UI 上创建了不同的文本展示元素,-textvariable选项监控给定的变量,并自动更新标签的值,这展示了全局变量LOW、HIGH、STATUS的绑定。
button行创建了 “Guess” 和 “Quit” 按钮,-command选项设定了当按钮被按下时要执行的操作。按下 “Guess” 按钮执行了上面的check_guess函数以检查用户输入的值。
entry部件更有趣。它创建了一个三字符宽的输入框,并将输入绑定到GUESS全局变量。它还通过-validatecommand选项设置了验证,阻止输入部件接收除数字以外的任何内容。
focus命令是用户界面的一项改进,使程序启动时输入部件处于激活状态。没有此命令,你需要先点击输入部件才可以输入。
bind命令允许你在按下回车键时自动点击 “Guess” 按钮。如果你记得check_guess中的内容,猜测正确之后会重新绑定回车键到 “Quit” 按钮。
最后,这部分设定了图形用户界面的布局:
grid stgrid .low .dash .highgrid .status .resultgrid .guess .entrygrid .quit
grid几何管理器被逐步调用,以逐渐构建出预期的用户体验。它主要设置了五行部件。前三行是显示不同值的标签,第四行是 “Guess” 按钮和entry部件,最后是 “Quit” 按钮。
程序到此已经初始化完毕,wishshell 进入事件循环,等待用户输入整数并按下按钮。基于其在被监视的全局变量中找到的变化,它会更新标签。
注意,输入光标开始就在输入框中,而且按下回车键将调用适当且可用的按钮。
这只是一个初级的例子,Tcl/Tk 有许多可以让间隔、字体、颜色和其他用户界面方面更具有吸引力的选项,这超出了本文中简单 UI 的示例。
运行这个应用,你可能会注意到这些部件看起来并不很精致或现代。这是因为我正在使用原始的经典部件集,它们让人回忆起 X Windows Motif 的时代。不过,还有一些默认的部件扩展,被称为主题部件,它们可以让你的应用程序有更现代、更精致的外观和感觉。
启动游戏!保存文件之后,在终端中运行它:
$ ./numgame.wish
在这种情况下,我无法给出控制台的输出,因此这里有一个动画 GIF 来展示如何玩这个游戏:
进一步了解 TclTcl 支持命名空间的概念,所以在这里使用的变量并不必须是全局的。你可以把绑定的部件变量组织进不同的命名空间。对于像这样的简单程序,可能并不太需要这么做。但对于更大规模的项目,你可能会考虑这种方法。
proc check_guess函数体内有一行global代码我之前没有解释。在 Tcl 中,所有变量都按值传递,函数体内引用的变量的范围是局部的。在这个情况下,我希望修改的是全局变量,而不是局部范围的版本。Tcl 提供了许多方法来引用变量,在执行堆栈的更高级别执行代码。在一些情况下,像这样的简单引用可能带来一些复杂性和错误,但是调用堆栈的操作非常有力,允许 Tcl 实现那些在其他语言中实现起来可能较为复杂的新的条件和循环结构。
最后,在这篇文章中,我没有提到几何管理器,它们用于以特定的顺序展示部件。只有被某种几何管理器管理的部件才能显示在屏幕上。grid 管理器相当简洁,它按照从左到右的方式放置部件。我使用了五个 grid 定义来创建了五行。另外还有两个几何管理器:place 和 pack。pack 管理器将部件围绕窗口边缘排列,而 place 管理器允许固定部件的位置。除这些几何管理器外,还有一些特殊的部件,如 canvas,text和panedwindow,它们可以容纳并管理其他部件。你可以在经典的 Tcl/Tk 参考指南,以及Tk 命令文档页上找到这些部件的全面描述。
继续学习编程Tcl 和 Tk 提供了一个简单有效的方法来构建图形用户界面和事件驱动应用程序。这个简单的猜数游戏只是你能用这些工具做到的事情的起点。通过继续学习和探索 Tcl 和 Tk,你可以打开构建强大且用户友好的应用程序的无数可能性。继续尝试,继续学习,看看你新习得的 Tcl 和 Tk 技能能带你到哪里。
(题图:MJ/40621c50-6577-4033-9f3c-8013bd0286f1)
via: https://opensource/article/23/4/learn-tcltk-wish--game
作者:James Farrell选题:lkxed译者:ChatGPT 校对:wxy
本文由 LCTT原创编译,Linux中国荣誉推出
【来源:南阳市教育局_宛教影像】
南阳教育网讯 (通讯员 尹秋斌 罗玉红 李艳平 王瑜文)为加深学生对文言实词的记忆、增强学生对文言文学习兴趣,提高文言文学习效率,2023年5月9日,新野县一高中高二语文教师开发出了两款检验学生文言文知识的小游戏。
该校高二语文组在组长詹维老师的统筹带领下,紧跟网络时代发展,借助电子白板,资深教师提供坚实的理论支持,年轻教师运用高超的技术手段,老少同心,自主探索出了两款检验学生文言知识的小游戏。
第一款是基础型小游戏,侧重对知识的初步记忆。比如,文言实词“安”的义项有:“安稳”、“安抚”、“哪里”、“养”、“安置”、“安逸”、“安于”等。将这些义项添加到游戏里,再设置一定量的干扰项,掺杂其中,由学生判断选择。为了增强游戏的竞技性,高二语文组王瑜雯老师还将游戏界面设置为双人模式,让两位同学进行比拼,极大激发了学生们的积极性和胜负欲;同时,文言实词的不同义项也在紧张刺激的游戏中被一一拿下。
第二款是拔高型小游戏,侧重对知识的深入理解,加大了难度。在文言文的学习上,学生只记忆实词的义项还不够,还需要在具体的文言语境里正确使用。比如文言实词“被”的义项有:“遭受”、“表被动”、“穿在身上”、“覆盖”、“披散”等,其中“秦王复击轲,被八创”中的“被”是“遭受”的意思;“妆成每被秋娘妒”中的“被”是“表被动”的意思,将这些具体的文言句以及对应意思设置在游戏中,再把某些实词意思替换成错误的义项,由学生进行判断。同样是双人竞技模式,让学生在比拼中记忆知识、加强理解,让课堂活起来,让学生乐起来。
游戏实验中,两名学生在讲台上比拼的同时,其他学生也争相大声支援,当然也有同学故意给出错误答案。经过不同班级的多次实践,在此模式下,整个课堂气氛活跃,学生参与度高,又难又枯燥的文言学习就此变得有趣高效起来。
声明:此文版权归原作者所有,若有来源错误或者侵犯您的合法权益,您可通过邮箱与我们取得联系,我们将及时进行处理。邮箱地址:jpbl@jp.jiupainews