简单介绍利用TK在Python下进行GUI编程的教程

我想要向您介绍能想像到的开始 GUI 编程的最简单方法,就是使用 Scriptics 的 TK 和 Tkinter 封装器。我们将与 developerWorks 中的 “Python 中的 curses 编程” 提到的 curses 库进行很多比较。除了 curses 实现文本控制台而 TK 实现 GUI 这一差别之外,这两个库有着惊人相似的接口。在使用任何一个库之前,需要基本了解窗口和事件循环,并参考可用的窗口小部件。(好,好的参考和适量的练习。)

如同关于 curses 的文章,本文仅讨论 Tkinter 本身的特性。既然很多 Python 发行版都带有 Tkinter,因此可能无需下载支持库或其它 Python 模块。本文后面的 参考资料 指向几个更高级别的用户接口窗口小部件的集合,但是您可以用 Tkinter 本身做许多事,包括构造自己的高级窗口小部件。学习基本 Tkinter 模块将为您引入 TK 的思维方式,即使您继续使用更高级的窗口小部件集合,这种思维方式仍十分重要。
TK 简要描述

TK 是与 TCL 语言关系最密切、且被广泛使用的图形库,TCL 语言和 TK 都由 John Ousterhout 开发。虽然 TK 于 1991 年作为 X11 库出现,但实际上它从那时起就被移植到每一种流行的 GUI。(它与 Python 逐渐拥有“标准”GUI 的情形相似。)现在,大多数流行语言和很多小型语言都有 TK 绑定(Tkinter 模块)。

在开始之前,我必须承认:我不是瘦小枯干的 TK 编程专家。事实上,我的大部分 TK 编程经验大约从我写这篇文章三天前才开始。那三天并非没有挑战,但是最后我觉得很好地掌握了 Tkinter。我在这里要说的是:TK 和 Tkinter 封装器设计得都非常好,便于用户操作,并且只是关于 GUI 编程最简单的介绍。

从测试应用程序开始

我们将使用 Txt2Html,这个在以前很多专栏(请参阅 参考资料 )中使用的文件格式转换程序,的封装器作为测试应用程序。虽然可以用几种方式运行 Txt2Html,但这里的封装器却要从命令行运行 Txt2Html。该应用程序以批处理进程的形式运行,并带有指出要执行的转换各方面特性的命令行自变量。(以后,最好为用户提供交互式选择屏幕选项,以在执行实际转换之前引导用户逐步选择不同的转换选项并提供所选选项的可视反馈。)

tk_txt2html 基于带有下拉菜单和嵌套子菜单的顶部菜单。旁边有详细的实现说明,它看起来与在 “Python 中的 Curses 编程” 中讨论的 curses 版本很相象。虽然 TK 用较少的代码可以实现更多的功能,但很明显,tk_txt2html 和 curses_txt2html 很相似。例如,在 TK 中,象菜单这样的特性可以依靠内置的 Tkinter 类实现,而无需从头编写。

除了设置配置选项之外,TK 封装器还包括一个与 TK Text 窗口小部件一起构建的滚动帮助框(一个带有 Message 窗口小部件的“关于”框)和一个进行 TK 动态几何管理的历史窗口。与大多数交互式应用程序一样,封装器用 TK 的 Entry 窗口小部件接受某些用户输入。

在进一步讨论代码之前,让我们看一下实际运行中的应用程序。

学习基本知识

实际上,Tkinter 程序只需做三件事:
最小的 [Tkinter] 程序

import Tkinter # import the Tkinter module
root = Tkinter.Tk() # create a root window
root.mainloop() # create an event loop

这是一个完全有效的 Tkinter 程序(不要介意它没有实际用处,因为它甚至不管理 "hello world")。该程序唯一需要做的是创建一些容纳其根窗口的窗口小部件。这样增强之后,无需程序员进一步干涉,该程序的 root .mainloop() 方法调用就可以处理所有用户交互。

main() 函数

现在,我们看一下 tk_txt2html.py 更现实的 main() 函数。请注意,我更喜欢使用 John Grayson 的 import Tkinter 语句,而不是 from Tkinter import (请参阅 参考资料 中所列的他的书籍)。这不是因为我担心名称空间的干扰( from ... import 语句的通常警告),而是因为我想明确使用 Tkinter 类;我不想冒险将它们与我自己的函数和类相混淆)。建议您也这样做,至少在开始时这样做。
tk_txt2html main() 函数

def main():
 global root, history_frame, info_line
 root = Tkinter.Tk()
 root.title('Txt2Html TK Shell')
 init_vars()
 #-- Create the menu frame, and menus to the menu frame
 menu_frame = Tkinter.Frame(root)
 menu_frame.pack(fill=Tkinter.X, side=Tkinter.TOP)
 menu_frame.tk_menuBar(file_menu(), action_menu(), help_menu())
 #-- Create the history frame (to be filled in during runtime)
 history_frame = Tkinter.Frame(root)
 history_frame.pack(fill=Tkinter.X, side=Tkinter.BOTTOM, pady=2)
 #-- Create the info frame and fill with initial contents
 info_frame = Tkinter.Frame(root)
 info_frame.pack(fill=Tkinter.X, side=Tkinter.BOTTOM)
 # first put the column labels in a sub-frame
 LEFT, Label = Tkinter.LEFT, Tkinter.Label # shortcut names
 label_line = Tkinter.Frame(info_frame, relief=Tkinter.RAISED, borderwidth=1)
 label_line.pack(side=Tkinter.TOP, padx=2, pady=1)
 Label(label_line, text="Run #", width=5).pack(side=LEFT)
 Label(label_line, text="Source:", width=20).pack(side=LEFT)
 Label(label_line, text="Target:", width=20).pack(side=LEFT)
 Label(label_line, text="Type:", width=20).pack(side=LEFT)
 Label(label_line, text="Proxy Mode:", width=20).pack(side=LEFT)
 # then put the "next run" information in a sub-frame
 info_line = Tkinter.Frame(info_frame)
 info_line.pack(side=Tkinter.TOP, padx=2, pady=1)
 update_specs()
 #-- Finally, let's actually do all that stuff created above
 root.mainloop()

在这个简单的 main() 函数中有几件事要注意:

每一个窗口小部件都有一个父代。每当创建窗口小部件时,传递给实例创建的第一个自变量是新的窗口小部件的父代。
    如果有其它窗口小部件创建自变量,将通过名称传递它们。Python 的这一特性给我们以指定选项或允许它们取缺省值的极大灵活性。
    有几个窗口小部件实例 (Frame) 是全局变量。可以通过在函数间传递变量来使它们成为本地变量,以便维护代码范围的理论纯洁性,但是与它的实际用处相比过于麻烦。另外,使这些基本的 UI 元素全局化强调了这样一个事实:它们可以在整个函数中使用。但是,要确保对自己的全局变量使用良好的命名规范。(事先给您一个警告,Python 人员看起来讨厌匈牙利符号。)
    创建完窗口小部件之后,我们调用一个几何图形管理器来让 TK 知道在哪里放置窗口小部件。TK 在计算细节信息时有许多魔力,特别是当调整窗口大小或动态添加窗口小部件时更是如此。但是在任何情况下,都需要让 TK 知道使用哪套咒语。

应用几何图形管理器

TK 提供三个几何图形管理器: .pack() 、 .grid() 和 .place() 。虽然 .place() 可用于精细(换句话说,非常复杂)的控制,但 tk_txt2html 只使用头两个。大多数时候,您将使用 .pack() 。

当然,可以不带自变量来调用 .pack() 方法。但是如果那样做,窗口小部件可能会在显示屏幕的某处结束,您可能也想为 .pack() 提供一些提示。这些提示中最重要的是 side 自变量。可能的值是 LEFT、RIGHT、TOP 和 BOTTOM(请注意这些是 Tkinter 名称空间中的变量)。

.pack() 的许多魔力来自可以将窗口小部件嵌套这一事实。特别的,除了作为其它窗口小部件的容器(它有时显示不同类型的边界)之外,Frame 窗口小部件几乎不作什么。这样,就可以很方便地在所希望的方向排列几个框架,然后在每个框架中添加其它窗口小部件。按照调用框架(以及其它窗口小部件)的 .pack() 方法的顺序来排列它们。因此,如果两个窗口小部件都请求 side=TOP ,则满足先进入的请求。

tk_txt2html 还偶尔使用 .grid() 。grid 几何图形管理器用可视的坐标线覆盖父代窗口小部件。当窗口小部件调用 .grid(row=3, column=4) 时,它请求其父代将它放在第三行第四列上。通过查看父代的所有子代的请求来计算父代的总行数和总列数。

别忘了对自己的窗口小部件应用几何图形管理器,以免在显示屏幕上看不到它们时后悔莫及。

菜单

Tkinter 能轻易生成菜单。虽然我们在这里使用十分简单的示例,但是如果愿意,还可以用不同的字体、图形、复选框和各种别致的子代窗口小部件来填充菜单。在我们的示例中,tk_txt2html 的菜单全部用我们在上面所见的行创建。

menu_frame.tk_menuBar(file_menu(), action_menu(), help_menu())

这行本身可能有些神秘。大多数必须完成的工作位于名为 *_menu() 的函数中。让我们看一下最简单的示例。
创建下拉菜单

def help_menu():
 help_btn = Tkinter.Menubutton(menu_frame, text='Help', underline=0)
 help_btn.pack(side=Tkinter.LEFT, padx="2m")
 help_btn.menu = Tkinter.Menu(help_btn)
 help_btn.menu.add_command(label="How To", underline=0, command=HowTo)
 help_btn.menu.add_command(label="About", underline=0, command=About)
 help_btn['menu'] = help_btn.menu
 return help_btn

下拉菜单是将 Menu 小窗口部件作为子代的 Menubutton 小窗口部件。 .pack() (或 .grid() 等)将 Menubutton 排列在适当的位置。Menu 小窗口部件用 .add_command() 方法添加项。(请注意上面为 Menubutton 的目录所作的奇怪分配。不要问为什么,跟着我这样做并在您自己的代码中也这样做即可。)

获得用户输入

下面将看到的示例演示 Label 小窗口部件 widget 如何显示输入(有关 Text 和 Message 小窗口部件的某些示例的完整资源,请参阅 参考资料 )。字段输入的基本小窗口部件是 Entry。它易于使用,但是如果以前曾使用过 Python 的 raw_input() 或 curses 的 .getstr() ,您将发现技巧略有不同。TK 的 Entry 小窗口部件不返回可分配的值。相反,它获取自变量来填充字段对象。例如,下面的函数允许用户指定输入文件。
接受用户字段输入

def GetSource():
 get_window = Tkinter.Toplevel(root)
 get_window.title('Source File?')
 Tkinter.Entry(get_window, width=30,
 textvariable=source).pack()
 Tkinter.Button(get_window, text="Change",
 command=lambda: update_specs()).pack()

这里有几件事要注意。我们为这个输入创建了一个新的 Toplevel 小窗口部件和对话框,并且通过创建一个带有 textvariable 自变量的 Entry 小窗口部件指定了输入字段。但是等一下,还有件事!

textvariable 自变量没有指定简单的字符串变量。相反,它引用一个 StringVar 对象。在我们的示例中,从 main() 调用的 init_vars() 函数包含三行。

source = Tkinter.StringVar()
source.set('txt2html.txt')

这创建了一个适用于用户输入的对象并为其分配了初始值。每次在与之相链接的 Entry 小窗口部件中进行更改时都立即修改该对象。每次在 Entry 小窗口部件中击键、而不是读取终止时,都进行 raw_input() 样式的更改。

要想获得户输入的值,我们使用 StringVar 实例的 .get() 方法。例如:

source_string = source.get()

结束语

此处所略述的技巧以及我们在完整的应用程序源代码中使用的技巧应该足以使您开始进行 Tkinter 编程了。略微实践之后您就会发现它不难掌握。有一个好处是:可以通过 Python 以外的很多语言访问 TK 库,因此您使用 Python 的 Tkinter 模块学到的大多数知识可以应用到其它语言。

(0)

相关推荐

  • Python Tkinter GUI编程入门介绍

    一.Tkinter介绍 Tkinter是一个python模块,是一个调用Tcl/Tk的接口,它是一个跨平台的脚本图形界面接口.Tkinter不是唯一的python图形编程接口,但是是其中比较流行的一个.最大的特点是跨平台,缺点是性能不太好,执行速度慢. 一般使用Tkinter的方法是: From Tkinter import * 或者: import Tkinter 两者的区别我们前面讲模块的时候已经说过了.   二.Tkinter的使用 先看一下GUI程序的开发,熟悉MFC的朋友应该不会陌生.

  • Python中使用Tkinter模块创建GUI程序实例

    使用Tkinter模块来创建简单的GUI程序. Tkinter的Widgets有:Button.Canvas.Checkbutton.Entry.Frame.Label.Listbox.Menu.Menubutton.Message.Radiobutton.Scales.Scrollbar.TEXT.Toplevel等. 例: 复制代码 代码如下: # This program displays an empty window. import Tkinter def main():   main

  • Python的GUI框架PySide的安装配置教程

    (一)说在前面 Python自带了GUI模块Tkinter,只是界面风格有些老旧.另外就是各种GUI框架了. 之前安装过WxPython,并做了简单的界面.遂最近又重新搜索了一下网上关于Python GUI框架的问题,发现还是Qt呀. Python的Qt有PyQt和PySide吧.PyQt 是商业及 GPL 的版权, 而 PySide 是 LGPL.大意也就是PyQt开发商业软件是要购买授权的,而PySide则不需要.二者代码基本一致,修改下import 基本剩余的代码皆可通用.所以毫不犹豫的选

  • 基于wxpython开发的简单gui计算器实例

    本文实例讲述了基于wxpython开发的简单gui计算器.分享给大家供大家参考.具体如下: # wxCalc1 a simple GUI calculator using wxPython # created with the Boa Constructor which generates all the GUI components # all I had to do is add some code for each button click event # Boa free from: h

  • 基于wxpython实现的windows GUI程序实例

    本文实例讲述了基于wxpython实现的windows GUI程序.分享给大家供大家参考.具体如下: # using a wx.Frame, wx.MenuBar, wx.Menu, wx.Panel, wx.StaticText, wx.Button, # and a wx.BoxSizer to show a rudimentary wxPython Windows GUI application # wxPython package from: http://prdownloads.sou

  • python开发之IDEL(Python GUI)的使用方法图文详解

    本文讲述了python开发之IDEL(Python GUI)的使用方法.分享给大家供大家参考,具体如下: 在安装完Python后,我们希望能够运用python GUI来运行一些我们编写的程序,那么Python GUI怎样用呢? 看完这篇blog,也许你就会使用Python GUI来编写你自己的程序了. 下面我们就来看看Python GUI是怎样使用的吧! 1. 新建一个文件 我们新建一个文件,名字随便,我这里命名为: test_hello.py 2. 用Python GUI打开文件 我们可以选择

  • 使用Python开发windows GUI程序入门实例

    今天终于可以用wxPython开发GUI程序了,非常高兴.把其中的一些注意点写下来以供参考.在windows XP平台下,首先需要做以下环境的配置: 1. 首先是安装python ,安装完之后将python/bin所在目录添加到path中. 2. 安装wxPython, 此时要注意wxPython的版本要与前面python的版本一致. 3. 安装py2exe, 这是windows平台下一个非常好的python程序发布工具,可以将python程序编译成exe而脱离python环境执行.做完上面的安

  • 简单介绍利用TK在Python下进行GUI编程的教程

    我想要向您介绍能想像到的开始 GUI 编程的最简单方法,就是使用 Scriptics 的 TK 和 Tkinter 封装器.我们将与 developerWorks 中的 "Python 中的 curses 编程" 提到的 curses 库进行很多比较.除了 curses 实现文本控制台而 TK 实现 GUI 这一差别之外,这两个库有着惊人相似的接口.在使用任何一个库之前,需要基本了解窗口和事件循环,并参考可用的窗口小部件.(好,好的参考和适量的练习.) 如同关于 curses 的文章,

  • 哪种Python框架适合你?简单介绍几种主流Python框架

    众所周知,Python开发框架大大减少了开发者不必要的重复劳动,提高了项目开发效率的同时,还使得创建的程序更加稳定.目前比较主流的Python框架都有哪些呢?一般大家用的比较多的是Django.Flask.Scrapy.Diesel.Cubes.Pulsar和Tornado.那么这些Python框架的区别是什么呢?下面我们一起来看看这些Python框架的不同适用环境. 1.Django 谈到Python框架,我们第一个想到的应该就是Django.Django作为一个Python Web应用开发框

  • 在Python下尝试多线程编程

    多任务可以由多进程完成,也可以由一个进程内的多线程完成. 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程. 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程. Python的标准库提供了两个模块:thread和threading,thread是低级模块,threading是高级模块,对thread进行了封装.绝大多数情况下,我们只需要使用threading

  • 初步解析Python下的多进程编程

    要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识. Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊.普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回. 子进程永远返回0,而父进程返回子进程的ID.这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用get

  • 用Python进行TCP网络编程的教程

    Socket是网络编程的一个抽象概念.通常我们用一个Socket表示"打开了一个网络链接",而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可. 客户端 大多数连接都是可靠的TCP连接.创建TCP连接时,主动发起连接的叫客户端,被动响应连接的叫服务器. 举个例子,当我们在浏览器中访问新浪时,我们自己的计算机就是客户端,浏览器会主动向新浪的服务器发起连接.如果一切顺利,新浪的服务器接受了我们的连接,一个TCP连接就建立起来的,后面的通信就是发送网页内容了. 所

  • 在双python下设置python3为默认的方法

    如何在双python下设置python3为默认 在C:\Program下举例 第一步安装好python2和python3后设置好环境变量 第二步去掉python2根目录下的python.exe文件,还有Scripts文件夹下的pip.exe文件 第二步复制python3根目录下的python3.exe文件新建python.exe,还有Scripts若不存在pip.exe,则复制pip3.exe新建pip.exe 执行结果如下,则说明配置成功 总结 以上所述是小编给大家介绍的在双python下设置

  • 解决win64 Python下安装PIL出错问题(图解)

    1.软件版本 首先我先安装了 python 2.7 pip是  8.1.2 2.当我要安装PIL时,我在cmd下面输入:pip install PIL 错误提示是: Could not find a version that satisfies the requirement PIL (from versions: ) No matching distribution found for PIL 3.错误原因:后来找了很多方法,发现我的电脑是64位的,而官网只提供32位的,就是自己去官网下载的其

  • Centos 6.5下安装MySQL 5.6教程

    1.下载Linux对应的RPM包 http://dev.mysql.com/downloads/mysql/5.6.html wget http://cdn.mysql.com//Downloads/MySQL-5.6/MySQL-5.6.33-1.el6.x86_64.rpm-bundle.tar 2.解压tar包 tar -xvf MySQL-5.6.33-1.el6.x86_64.rpm-bundle.tar 3.安装MySQL rpm -ivh MySQL-server-5.6.33-1

  • PyCharm导入python项目并配置虚拟环境的教程详解

    进入PyCharm后,点击File→Open,然后在弹窗中选择需要导入项目的文件夹: 打开了python项目后,需要配置该项目对应的python才可以正常运行: 配置步骤:File→settings 在设置弹窗中选择Project Interpreter,然后点击add: 在弹窗中,选择Existing environment,路径可以选择python项目的路径: 然后就大功告成了,可以去试着运行你的程序了~ 总结 以上所述是小编给大家介绍的PyCharm导入python项目并配置虚拟环境的教程

  • mysql8.0.18下安装winx64的详细教程(图文详解)

    到网站 https://dev.mysql.com/downloads/mysql/ 下载MySQL数据库 解压后进入目录 D:\Program Files\mysql-8.0.18 创建my.ini文件 [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8mb4 [mysqld] # 设置3306端口 port = 3306 # 设置mysql的安装目录 basedir=D:\\Program Files\\mysql-8.0.18 # 设置

随机推荐