网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
在正式讲解 Tkinter 之前,我们有必要对“图形用户界面”这一名词做简单的介绍。
如果您是第一次接触“图形用户界面”这个名词,一定会比较迷茫,其实在我们的日常工作与学习中,我们经常与它“相遇”,举一个简单的例子,当打开腾讯 QQ 后,在电脑桌面上会弹出 QQ 的登录界面,成功登录 QQ 后会显示 QQ 的主界面,这些都可以被称作图形用户界面,它的任务就是完成与用户的交互,如下所示:
图1:QQ登录界面
再比如 Windows 操作系统的电脑桌面,本质上也是“图形用户界面”,只不过与 APP 相比,计算机用户界面更为复杂,在桌面上出现的任何一个弹出框都可以看做是一个“图形用户界面”如下所示:
图2:系统信息界面
GUI发展史
上世纪 70 年代,美国施乐研究中心完成了第一个比较完善的图形界面程序(即 WIMP 程序),该程序包含了窗口、图标、菜单和下拉菜单等。随后世界著名的苹果公司于 1983 年发布了一款电子图表软件(Lisa),这也是世界上第一款具有完整界面的计算机软件。
然而,图形用户界面的真正火热,是伴随着 Windows 系统的出现而兴盛起来的。
20 世纪初,微软相继发布了 Windows 95、Windows 98、Windows XP 等版本,其中 Windows XP 更是直接奠定了微软在操作系统领域的“霸主”地位,此时的计算机图形界面才日趋为完善和成熟起来。如果您接触过微软公司开发的 VB(Visual Basic)程序语言,您就能体验到微软在 GUI 方面功力深厚。VB 语言拥有许多 GUI 控件,通过这些可视化控件能够迅速建立一个应用程序。
不难看出,虽然苹果公司在 GUI 领域起步较早,但却被微软后来者居上,至于 Linux 系统,它的的图形界面则起步更晚。
在 GUI 发展的过程中,微软、苹果、施乐等公司为 GUI 领域的发展做了重要贡献。图形用户界面是人类历史上最伟大的发明创造之一,它对计算机的普及与进一步发展起到了意义深远的影响。
总结:
经过上述介绍,我们知道,图形用户界面(即 GUI)指的是采用图形方式来显示计算机的用户操作界面,它是人与计算机交互的一种方式。用户通过鼠标、键盘、触摸等操作来控制屏幕上的图标、菜单等选项卡,从而实现选择功能,或者启动程序等操作。
GUI应用领域
GUI 的应用领域非常广泛,它不仅仅局限于软件产品(app)、计算机操作系统界面,还囊括了车载系统产品、智能家居、电子数码等产品,比如汽车中控台的显示屏界面,或者行车记录仪界面等等。
图3:汽车中控台显示屏
GUI的优势
GUI 在互联网行业中有着举足轻重的地位,那些专门从事于界面开发的程序员被称为 GUI 开发工程师,如果在细分的话,可分为软件界面开发工程师和硬件界面开发工程师,它们统称为“界面开发程序员”。当然界面开发工作也需要配合其他岗位一起完成,比如前端 UI 工程师(User Interface Designer),他们主要负责界面的美化和设计等工作。
与早期的命令行界面相比,图形界面对于用户更加友好,使用户在视觉上更容易接受。由于 GUI 直接与用户交互,因此它不仅仅是计算机中的一门技术,它还涉及了美学、行为学、心里学等许多领域的知识。因此在开发、设计一款 GUI 产品时,不能只局限于技术层面,而要对全局进行把控,最终使产品更符合人性化,从而提高用户的使用体验。
GUI开发工具
目前市面上的 GUI 开发软件包有很多,其中多数使用 C/C++ 语言开发,其中较为流行的框架有 Qt 、GTK、wxWidgets、Electron、MFC/ATL(微软公司开发) 等。Electron 较为特殊,它是由 C/C++ 和 JS、TypeScript 开发而成,它通过 JavaScript、HTML 和 CSS 来构建跨平台的桌面应用程序,这在以前是不可想象的。
图4:GUI 开发工具 Electron
Qt 是由 Qt Company 开发的一个跨平台的 C++ 框架(现已被 Digia 公司收购),目前最新的版本是 Qt5。Qt 除了支持界面设计(GUI编程),还封装了与网络编程、多线程、数据库连接、视频音频等相关的功能。
图5:GUI Qt 图标
C语言中文网推出了《Qt教程》,如果想深入了解,请点击学习。
您可能会问,为什么要采用 C/C++ 库来开发 GUI 软件包呢?这是因为相比于其他语言,C/C++ 更适合于开发 GUI 程序。我们知道 GUI 程序其实就是人和计算机的交互操作,因此程序的运行性能是考虑的第一要素,若性能不佳,将非常影响用户的体验。 C/C++ 作为执行效率仅次于汇编语言的编译型语言,用来开发 GUI 软件包在合适不过了。
除 C/C++ 之外,Python、Java、C# 等语言也提供了一些 GUI 开发软件包,如下所示:
- Python GUI 工具:Tkinter、wxPython、PyQt、PyGTK、Pywin32 等;
- Java GUI 工具:AWT、SWING、JavaFX 等;
- C# GUI 工具: WinForm、WPF 等;
虽然上述语言的性能不及 C/C++,但是它们的开发效率很高,因此在性能要求不高的情况下,这些软件包也能够满足大多数用户的需求。大家要铭记,开发 GUI 程序的目的是为了实现人机交互,提升设备或者 APP 软件的易用性,这是 GUI 程序的初衷。
Tkinter是什么
在《GUI是什么》一节,我们了解了 GUI(图形用户界面)的相关概念,接下来我们正式介绍本教程的主人公 —— Tkinter。
Tkinter(即 tk interface,简称“Tk”)本质上是对 Tcl/Tk 软件包的 Python 接口封装,它是 Python 官方推荐的 GUI 工具包,属于 Python 自带的标准库模块,当您安装好 Python 后,就可以直接使用它,而无须另行安装。
作为一款 Python GUI 工具,Tkinter 拥有良好的跨平台性,支持 Windows、Linux、Mac 平台,它传承了 Python 语法简洁、代码易读的基本特点。
与其他编程语言的 GUI 工具包相比,Tkinter 编码效率高,能够实现快速开发的目的,非常适合初学者学习。Tkinter 使用纯 Python 语言开发,与 C/C++ 开发的 Qt 框架相比,Tkinter 有自身的局限性,比如性能、功能丰富程度等都不及 Qt,因此它只适合开发一些简单的程序,比如计算器的界面,或者一个简易的聊天窗口等。如下图所示:
图1:Tkinter开发的聊天窗口
通常情况下不会使用 Tkinter 来开发较为复杂的桌面应用程序,这是由 Python 语言自身特点决定的,作为一种解释型语言和脚本语言,Python 并不具备开发复杂桌面应用的优势。
但“麻雀虽小,五脏俱全”,Tkinter 作为 Python GUI 开发工具之一,它具有 GUI 软件包的必备的常用功能。比如,它提供了十多种不同类型的窗口控件、窗口布局管理器、事件处理机制等,加之其开发效率高、代码简洁易读, Tkinter 自问世以来,备受大家青睐。当您想要制作一个小工具的界面或者比较简单的桌面应用程序时,那么Tkinter 将是一个不错的选择。
在 CMD 命令行运行以下命令,可以查看 Tkinter 的相应版本,同时也会显示一个简易的窗口,命令如下:
python -m tkinter
显示出的窗口如下所示:
图2:显示的窗口
Python 官方提供的 IDLE(Integrated Development and Learning Environmen,集成开发和学习环境),就是使用完全使用 Tkinter 开发而成的,如下所示:
图3:Python IDLE集成开发环境
无论您是学习 Tkinter ,亦或是学习其他语言的 GUI 软件包,下列给出几点学习建议,帮助您找到学习 GUI 编程的方法:
Tk 提供了诸多窗口控件(后续将详细讲解),这些控件形状各异,功能也不尽相同,在编写 GUI 程序的过程中,您可以把这些控件看做一块块的“积木”,而搭建积木这项工程,不仅要求您了解每块积木的形状(即控件作用),更重要是学会搭建积木的方法,学会如何摆放这些积木。只有这样,最终才能将这些积木构建一个完整、美观的“图形界面”。
本套教程,在介绍控件用法的同时,更注重讲解“搭建”方法,让您真正明白和掌握 GUI 编程。
Tkinter 中会涉及一些 GUI 编程的概念,比如根窗口(root)、顶级窗口(TopLeve)、Canvas(画布)、Frame(容器)、标签(Lable)等,对这些概念的理解,将有助于您理解 GUI 编程的逻辑思路,这样当您在使用 Tkinter 编程时就会得心应手。
第一个Tkinter程序
本节使用 Tkinter 编写第一个 GUI 程序,通过对程序代码的详细解读来讲解 Tkinter 的编码逻辑,以及使用 Tkinter 过程中的一些注意事项。
注意:程序中涉及的其他知识点(比如控件参数等)会在后续内容做详细介绍。
一个最简单的 Tkinter 程序至少应包含以下四个部分:
- 导入 tkinter 模块
- 创建主窗口,也称 root 窗口(即根窗口)
- 添加人机交互控件,同时编写相应的事件函数
- 通过主循环(mainloop)来显示主窗口
上述四个步骤中,只有第三步属于 Tkinter 编程的重点,其余三个步骤属于固定的代码格式,如下所示:
# -*- coding:utf-8 -*-
import tkinter as tk
# 调用Tk()创建主窗口
root_window =tk.Tk()
# 给主窗口起一个名字,也就是窗口的名字
root_window.title('C语言中文网:c.biancheng.net')
#开启主循环,让窗口处于显示状态
root_window.mainloop()
程序运行后结果如下:
图1:程序运行结果
上述代码创建了一个没有添加任何交互控件的 Tkinter 程序,它也是最简单的 GUI 程序。这里的主窗口相当于画板,其他的控件都要建立在主窗口之上。主循环也称“消息循环”或“事件循环”其的作用是让主窗口处于显示状态。
下面我们对上述程序做一下简单的改动,添加一些简单的交互控件(比如文本和按钮),代码如下所示:
# -*- coding:utf-8 -*-
import tkinter as tk
root_window =tk.Tk()
# 设置窗口title
root_window.title('C语言中文网:c.biancheng.net')
# 设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
root_window.geometry('450x300')
# 更改左上角窗口的的icon图标,加载C语言中文网logo标
root_window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
# 设置主窗口的背景颜色,颜色值可以是英文单词,或者颜色值的16进制数,除此之外还可以使用Tk内置的颜色常量
root_window["background"] = "#C9C9C9"
# 添加文本内,设置字体的前景色和背景色,和字体类型、大小
text=tk.Label(root_window,text="C语言中文网,欢迎您",bg="yellow",fg="red",font=('Times', 20, 'bold italic'))
# 将文本内容放置在主窗口内
text.pack()
# 添加按钮,以及按钮的文本,并通过command 参数设置关闭窗口的功能
button=tk.Button(root_window,text="关闭",command=root_window.quit)
# 将按钮放置在主窗口内
button.pack(side="bottom")
#进入主循环,显示主窗口
root_window.mainloop()
程序的运行结果如下:
图2:程序运行结果
下面对上述示例进行简单的分析:
1) 主窗口设置
上述程序,主要对主窗口的大小、背景颜色以及左上角的 icon 图标进行了设置,这些代码简洁易读,很容易理解。
2) 添加文本
上述程序中,我们添加了一行文本“C语言中文网,欢迎您”,此处使用了标签 Lable 控件来实现。需要注意的是,当成功创建标签(文本)对象后,必须使用 pack 方法将其放置在主窗口内(pack 方法又称窗口布局管理器)。主窗口是其他一切控件的基础,其他内容元素都要附着在主窗口上,就如同在一块画板上添加描述文字一样。下面再次回顾一下放置文本的代码:
# 添加文本标签,text参数指定内容
text=tk.Label(root_window,text="C语言中文网,欢迎您",bg="yellow",fg="red",font=('Times', 20, 'bold italic'))
# 将标签对象放置在主窗口内
text.pack()
3) 添加按钮
添加按钮的逻辑和添加文本标签类似,值得注意的是,按钮控件通过command
参数实现了“关闭窗口”功能,代码如下:
# 添加按钮
button=tk.Button(root_window,text="关闭",command=root_window.quit)
# 这里将按钮放置在主窗口的底部
button.pack(side="bottom")
Tkinter 提供了十余种常用类型的控件,每个控件都有相应的属性,比如颜色(前景色/背景色/颜色常量)、文本内容、字体样式、控件大小、控件样式、控件命令等等,这些会在后续内容做详细介绍。
4) 独立运行tkinter程序
上述程序是在 IDLE 环境下运行的,但如果脱离了开发环境,怎么做才能让 Tkinter 程序独立运行呢?
在 Windows 系统下,我们可以使用 Python 解释器来运行程序文件,首先将程序文件保存至桌面,然后启动 Python 解释器,执行程序,如下所示:
C:\Users\Administrator>python C:\Users\Administrator\Desktop\hello.py
上述方法需要依赖于 Python 解释器,当我们关闭解释器窗口时,GUI 程序也随之关闭。
如果想让程序独立的运行在 Windows 环境下,而不受 Python 解释器的影响,就需要将程序代码存储为.pyw
文件,并使用 Pythonw.exe 来执行程序,如下所示:
C:\Users\Administrator>pythonw.exe C:\Users\Administrator\Desktop\hello.py
执行后,当我们关闭控制台窗口时(即执行程序的 CMD 界面),GUI 程序不会随之而关闭,而是独立地显示在桌面上。
希望大家可以将本篇文章通读几遍,相信您一定会大有收获,这为后续知识的学习打下坚实的基础。
Tkinter常用控件和属性
我们知道,一个完整的 GUI 程序,其实是由有许多小的控件(widgets)构成的,比如按钮、文本框、输入框、选择框、菜单栏等等。在学习 Tkinter GUI 编程的过程中,不仅要学会如何摆放这些控件,还是掌握各种控件的功能、属性。只有这样才能开发出一个界面设计优雅,功能设计完善的 GUI 程序。
在创作本套教程的过程中,我们以控件的功能、属性作为切入点进行讲解。只有了解了控件的基本功能,才能在编程时得心应手。
控件类型
下表列出了 Tkinter 中常用的 15 个控件:
控件类型 | 控件名称 | 控件作用 |
---|---|---|
Button | 按钮 | 点击按钮时触发/执行一些事件(函数) |
Canvas | 画布 | 提供绘制图,比如直线、矩形、多边形等 |
Checkbutton | 复选框 | 多项选择按钮,用于在程序中提供多项选择框 |
Entry | 文本框输入框 | 用于接收单行文本输入 |
Frame | 框架(容器)控件 | 定义一个窗体(根窗口也是一个窗体),用于承载其他控件,即作为其他控件的容器 |
Lable | 标签控件 | 用于显示单行文本或者图片 |
LableFrame | 容器控件 | 一个简单的容器控件,常用于复杂的窗口布局。 |
Listbox | 列表框控件 | 以列表的形式显示文本 |
Menu | 菜单控件 | 菜单组件(下拉菜单和弹出菜单) |
Menubutton | 菜单按钮控件 | 用于显示菜单项 |
Message | 信息控件 | 用于显示多行不可编辑的文本,与 Label控件类似,增加了自动分行的功能 |
messageBox | 消息框控件 | 定义与用户交互的消息对话框 |
OptionMenu | 选项菜单 | 下拉菜单 |
PanedWindow | 窗口布局管理组件 | 为组件提供一个框架,允许用户自己划分窗口空间 |
Radiobutton | 单选框 | 单项选择按钮,只允许从多个选项中选择一项 |
Scale | 进度条控件 | 定义一个线性“滑块”用来控制范围,可以设定起始值和结束值,并显示当前位置的精确值 |
Spinbox | 高级输入框 | Entry 控件的升级版,可以通过该组件的上、下箭头选择不同的值 |
Scrollbar | 滚动条 | 默认垂直方向,鼠标拖动改变数值,可以和 Text、Listbox、Canvas等控件配合使用 |
Text | 多行文本框 | 接收或输出多行文本内容 |
Toplevel | 子窗口 | 在创建一个独立于主窗口之外的子窗口,位于主窗口的上一层,可作为其他控件的容器 |
在后续内容中,我们会陆续对上表中涉及的控件进行介绍。当然,除了上述控件外,还有一些高级控件,比如 PanedWindow、messagebox、LableFrame、Spinbox,在后续章节也会讲解。
控件基本属性
从上表来看,每个控件都有着各自不同的功能,即使有些控件功能相似,但它们的适用场景也不同。
在 Tkinter 中不同的控件受到各自参数的约束(即参数),所有控件既有相同属性,也有各自独有的属性。本节内容,先对这些控件的共用属性做简单介绍,如下表所示:
属性名称 | 说明 |
---|---|
anchor | 定义控件或者文字信息在窗口内的位置 |
bg | bg 是 background 的缩写,用来定义控件的背景颜色,参数值可以颜色的十六进制数,或者颜色英文单词 |
bitmap | 定义显示在控件内的位图文件 |
borderwidth | 定于控件的边框宽度,单位是像素 |
command | 该参数用于执行事件函数,比如单击按钮时执行特定的动作,可将执行用户自定义的函数 |
cursor | 当鼠标指针移动到控件上时,定义鼠标指针的类型,字符换格式,参数值有 crosshair(十字光标)watch(待加载圆圈)plus(加号)arrow(箭头)等 |
font | 若控件支持设置标题文字,就可以使用此属性来定义,它是一个数组格式的参数 (字体,大小,字体样式) |
fg | fg 是 foreground 的缩写,用来定义控件的前景色,也就是字体的颜色 |
height | 该参数值用来设置控件的高度,文本控件以字符的数目为高度(px),其他控件则以像素为单位 |
image | 定义显示在控件内的图片文件 |
justify | 定义多行文字的排列方式,此属性可以是 LEFT/CENTER/RIGHT |
padx/pady | 定义控件内的文字或者图片与控件边框之间的水平/垂直距离 |
relief | 定义控件的边框样式,参数值为FLAT(平的)/RAISED(凸起的)/SUNKEN(凹陷的)/GROOVE(沟槽桩边缘)/RIDGE(脊状边缘) |
text | 定义控件的标题文字 |
state | 控制控件是否处于可用状态,参数值默认为 NORMAL/DISABLED,默认为 NORMAL(正常的) |
width | 用于设置控件的宽度,使用方法与 height 相同 |
注意:对于上述属性先做大体的了解即可,因为后续章节会对这些控件做更为详细的介绍。
Tkinter主窗口
主窗口控件(window)是一切控件的基础,它好比是一台高速运转的机器,而其他控件则相当于这台机器上的部件,比如齿轮、链条、螺丝等等。由此我们知道,主窗口是一切控件的基础,所有的控件的都需要通过主窗口来显示。
Tkinter 提供了一些关于主窗口对象的常用方法,在本节对这些方法做简单的介绍。
创建一个空白窗口
Tkinter 能够很方便地创建一个空白窗口,示例代码如下:
# 导入tk
from tkinter import \*
# 创建一个主窗口对象
window = Tk()
# 调用mainloop()显示主窗口
window.mainloop()
程序运行结果如下:
图1:程序运行结果
1) 窗口常用方法
下表列出了窗口的常用方法,其中 window 代表主窗口对象:
函数 | 说明 |
---|---|
window.title(“my title”) | 接受一个字符串参数,为窗口起一个标题 |
window.resizable() | 是否允许用户拉伸主窗口大小,默认为可更改,当设置为 resizable(0,0)或者resizable(False,False)时不可更改 |
window.geometry() | 设定主窗口的大小以及位置,当参数值为 None 时表示获取窗口的大小和位置信息。 |
window.quit() | 关闭当前窗口 |
window.update() | 刷新当前窗口 |
window.mainloop() | 设置窗口主循环,使窗口循环显示(一直显示,指导窗口被关闭) |
window.iconbitmap() | 设置窗口左上角的图标(图标是.ico文件类型) |
window.config(background =“red”) | 设置窗口的背景色为红色,也可以接受 16 进制的颜色值 |
window.minsize(50,50) | 设置窗口被允许调整的最小范围,即宽和高各50 |
window.maxsize(400,400) | 设置窗口被允许调整的最大范围,即宽和高各400 |
window.attributes(“-alpha”,0.5) | 用来设置窗口的一些属性,比如透明度(-alpha)、是否置顶(-topmost)即将主屏置于其他图标之上、是否全屏(-fullscreen)全屏显示等 |
window.state(“normal”) | 用来设置窗口的显示状态,参数值 normal(正常显示),icon(最小化),zoomed(最大化), |
window.withdraw() | 用来隐藏主窗口,但不会销毁窗口。 |
window.iconify() | 设置窗口最小化 |
window.deiconify() | 将窗口从隐藏状态还原 |
window.winfo_screenwidth() window.winfo_screenheight() | 获取电脑屏幕的分辨率(尺寸) |
window.winfo_width() window.winfo_height() | 获取窗口的大小,同样也适用于其他控件,但是使用前需要使用 window.update() 刷新屏幕,否则返回值为1 |
window.protocol(“协议名”,回调函数) | 启用协议处理机制,常用协议有 WN_DELETE_WINDOW,当用户点击关闭窗口时,窗口不会关闭,而是触发回调函数。 |
下面通一个示例对上述表格中的常用方法做简单地介绍:
import tkinter as tk
window =tk.Tk()
#设置窗口title
window.title('C语言中文网')
#设置窗口大小:宽x高,注,此处不能为 "\*",必须使用 "x"
window.geometry('450x300')
# 获取电脑屏幕的大小
print("电脑的分辨率是%dx%d"%(window.winfo_screenwidth(),window.winfo_screenheight()))
# 要求窗口的大小,必须先刷新一下屏幕
window.update()
print("窗口的分辨率是%dx%d"%(window.winfo_width(),window.winfo_height()))
# 如使用该函数则窗口不能被拉伸
# window.resizable(0,0)
# 改变背景颜色
window.config(background="#6fb765")
# 设置窗口处于顶层
window.attributes('-topmost',True)
# 设置窗口的透明度
window.attributes('-alpha',1)
# 设置窗口被允许最大调整的范围,与resizble()冲突
window.maxsize(600,600)
# 设置窗口被允许最小调整的范围,与resizble()冲突
window.minsize(50,50)
#更改左上角窗口的的icon图标,加载C语言中文网logo标
window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
#添加文本内容,并对字体添加相应的格式 font(字体,字号,"字体类型")
text=tk.Label(window,text="C语言中文网,网址:c.biancheng.net",bg="yellow",fg="red",font=('Times', 15, 'bold italic underline'))
#将文本内容放置在主窗口内
text.pack()
# 添加按钮,以及按钮的文本,并通过command 参数设置关闭窗口的功能
button=tk.Button(window,text="关闭",command=window.quit)
# 将按钮放置在主窗口内
button.pack(side="bottom")
#进入主循环,显示主窗口
window.mainloop()
程序的输出结果:
电脑的分辨率是1366x768
窗口的分辨率是450x300
程序运行效果图:
图2:程序运行结果
2) protocol协议处理机制
Tinter 除了提供事件绑定机制之外,还提供了协议处理机制,它指的是应用程序和窗口管理器之间的交互,最常用的协议为 WM_DELETE_WINDOW。
当 Tkinter 使用 WM_DELETE_WINDOW 协议与主窗口进行交互时,Tkinter 主窗口右上角x
号的关闭功能失效,也就是无法通过点击x
来关闭窗口,而是转变成调用用户自定义的函数。
下面看一组简单的示例:
from tkinter import Tk
# 导入 对话框控件
from tkinter import messagebox
# 创建主窗口
root = Tk()
# 定义回调函数,当用户点击窗口x退出时,执行用户自定义的函数
def QueryWindow():
# 显示一个警告信息,点击确后,销毁窗口
if messagebox.showwarning("警告","出现了一个错误"):
# 这里必须使用 destory()关闭窗口
root.destroy()
# 使用协议机制与窗口交互,并回调用户自定义的函数
root.protocol('WM\_DELETE\_WINDOW', QueryWindow)
root.mainloop()
程序运行结果:
图3:程序运行结果
通过封装函数的形式来执行相应的 GUI 控件功能,这在学习 Tkinter 编程的整个过程中非常常见,比如 Button 控件的command
参数也可以执行回调函数,如下所示:
import tkinter as tk
# 定义窗口
window = tk.Tk()
window.title('c语言中文网')
window.geometry('300x300')
window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
# 定义回调函数
def callback():
print("执行回调函数","C语言中文网欢迎您")
# 点击执行按钮
button = tk.Button(window, text="执行", command=callback)
button.pack()
window.mainloop()
点击窗口内的“执行”按钮,运行结果如下:
执行回调函数 C语言中文网欢迎您
设置窗的位置
当我们运行 Tkinter 程序时,主窗口都会出现在距离屏幕左上角指定的位置上,这是由 Tkinter 软件包默认设置的。但是在许多情况下,我们需要根据实际情况来移动窗口在电脑屏幕上的位置,这时应该如何处理呢?其实很简单,通过窗口对象的 geometry() 方法即可改变主窗口的位置,其语法格式如下:
geometry('450x400+300+200')
上述代码表示,设置主窗口的宽度为 450,高度为 400,同时窗口距离左边屏幕的距离为 300(以像素为单位),距离屏幕顶部的距离为 200,这里我们将带“+”的参数值称为“位置参数”,当然,您也可以将它们设置为负数,如下所示:
geometry('+-1500+-2000')
当设置了一个超过屏幕的负参数值时,主窗口会被移动至“屏幕之外”,此时就看不到主窗口了,这也是隐藏窗口的一种方法。
下面看一组简单的示例:
import tkinter as tk
window = tk.Tk()
window.title('c语言中文网')
window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
# 设置窗口大小变量
width = 300
height = 300
# 窗口居中,获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
screenwidth = window.winfo_screenwidth()
screenheight = window.winfo_screenheight()
size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2)
window.geometry(size_geo)
window.mainloop()
程序运行后窗口将出现在屏幕的中间位置,如下所示:
图4:程序运行结果
Tkinter Label标签控件
Label(标签)控件,是 Tkinter 中最常使用的一种控件,主要用来显示窗口中的文本或者图像,并且不同的 Lable(标签)允许设置各自不同的背景图片。
下面对 Label(标签)的常用属性做简单介绍:
属性名称 | 说明 |
---|---|
anchor | 控制文本(或图像)在 Label 中显示的位置(方位),通过方位的英文字符串缩写(n、ne、e、se、s、sw、w、nw、center)实现定位,默认为居中(center) |
bg | 用来设置背景色 |
bd | 即 borderwidth 用来指定 Label 控件的边框宽度,单位为像素,默认为 2 个像素 |
bitmap | 指定显示在 Label 控件上的位图,若指定了 image 参数,则该参数会被忽略 |
compound | 控制 Lable 中文本和图像的混合模式,若选项设置为 CENTER,则文本显示在图像上,如果将选项设置为 BOTTOM、LEFT、RIGHT、TOP,则图像显示在文本旁边。 |
cursor | 指定当鼠标在 Label 上掠过的时候,鼠标的的显示样式,参数值为 arrow、circle、cross、plus |
disableforeground | 指定当 Label 设置为不可用状态的时候前景色的颜色 |
font | 指定 Lable 中文本的 (字体,大小,样式)元组参数格式,一个 Lable 只能设置一种字体 |
fg | 设置 Label 的前景色 |
height/width | 设置 Lable 的高度/宽度,如果 Lable 显示的是文本,那么单位是文本单元,如果 Label 显示的是图像,那么单位就是像素,如果不设置,Label 会自动根据内容来计算出标签的高度 |
highlightbackground | 当 Label 没有获得焦点的时候高亮边框的颜色,系统的默认是标准背景色 |
highlightcolor | 指定当 Lable 获得焦点的话时候高亮边框的颜色,系统默认为0,不带高亮边框 |
image | 指定 Label 显示的图片,一般是 PhotoImage、BitmapImage 的对象 |
justify | 表示多行文本的对齐方式,参数值为 left、right、center,注意文本的位置取决于 anchor 选项 |
padx/pady | padx 指定 Label 水平方向上的间距(即内容和边框间),pady 指定 Lable 水平方向上的间距(内容和边框间的距离) |
relief | 指定边框样式,默认值是 “flat”,其他参数值有 “groove”、“raised”、“ridge”、“solid"或者"sunken” |
state | 该参数用来指定 Lable 的状态,默认值为"normal"(正常状态),其他可选参数值有"active"和"disabled" |
takefocus | 默认值为False,如果是 True,表示该标签接受输入焦点 |
text | 用来指定 Lable 显示的文本,注意文本内可以包含换行符 |
underline | 给指定的字符添加下划线,默认值为 -1 表示不添加,当设置为 1 时,表示给第二个文本字符添加下划线。 |
wraplength | 将 Label 显示的文本分行,该参数指定了分行后每一行的长度,默认值为 0 |
1) Label控件构成
一个控件主要由背景和前景两部分组成。其中背景由三部分构成分别是内容区域、填充区、边框,这三个区域的大小通过以下属性进行控制,如下所示:
- width/height
- padx/pady
- borderwidth
下面通过一个示意图对 Label 背景的区域构成进行说明:
图1:Label控件组成
边框的宽度可以通过 borderwidth 来调整,其样式可以通过relief
来设置(默认为平的 flat);填充区的大小调整分为水平方向和垂直方向,可以使用padx
和pady
来调整;内容区则主要用来显示文字或者图片,其大小由 width/height 来控制。
下面看一组简单的示例,代码如下所示:
import tkinter as tk
win = tk.Tk()
win.title("C语言中文网")
win.geometry('400x200')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 若内容是文字则以字符为单位,图像则以像素为单位
label = tk.Label(win, text="网址:c.biancheng.net",font=('宋体',20, 'bold italic'),bg="#7CCD7C",
# 设置标签内容区大小
width=30,height=5,
# 设置填充区距离、边框宽度和其样式(凹陷式)
padx=10, pady=15, borderwidth=10, relief="sunken")
label.pack()
win.mainloop()
程序运行结果,如下所示:
图2:设置Label标签
2) 标签添加背景图
Label(标签)除了可以显示文本之外,还可以用来显示图片,通过一组示例做简单的说明,代码如下所示:
import tkinter as tk
win = tk.Tk()
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
#显示图片(注意这里默认支持的图片格式为GIF)
photo = tk.PhotoImage(file = 'C:/Users/Administrator/Desktop/c.biancheng.gif')
print(type(photo))
# 将图片放在主窗口的右边
lab =tk.Label(win,image=photo).pack(side="right")
# 显示文字,设置文本格式
text = "C语言中文网欢迎您,\n"\
"这里有精彩的教程,\n "\
"这里有数不尽的知识宝藏"
lab_text =tk.Label(win,text=text,fg ='#7CCD7C',font=('微软雅黑',15,'italic'),justify='left',padx=10).pack(side='left')
win.mainloop()
程序运行结果:
图3:程序运行结果
注意:不同的 TK 版本所支持的图片格式也不完全相同,通过对上述示例的测试,此处只支持显示 GIF 格式的图片。
3) Message控件
Message 控件与 Label 控件的功能类似,它主要用来显示多行不可编辑的文本信息,与 Label 的不同之处在于该控件增加了自动分行的功能。下面对它做简单的介绍,示例如下:
from tkinter import *
#创建主窗口
win = Tk()
win.config(bg='#8DB6CD')
win.title("C语言中文网")
win.geometry('400x300')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
txt = "C语言中文网,网址是:c.biancheng.net"
msg = Message (win, text=txt,width =60,font=('微软雅黑',10,'bold'))
msg .pack (side=LEFT)
#开始程序循环
win .mainloop ()
程序运行结果:
图4:Tkinter Message控件
Tkinter Button按钮控件
Button 控件是 Tkinter 中常用的窗口部件之一,同时也是实现程序与用户交互的主要控件。通过用户点击按钮的行为来执行回调函数,是 Button 控件的主要功用。首先自定义一个函数或者方法,然后将函数与按钮关联起来,最后,当用户按下这个按钮时,Tkinter 就会自动调用相关函数。
按钮控件使用起来非常简单,它同样可以包含文本、图像、位图,并通过command
参数回调函数。当然按钮也并非一定要执行回调函数(callback function),它也只可以当一个“摆设”,不过这样的按钮是没有“灵魂的”,Button 控件的使用流程如下所示:
import tkinter as tk
# 创建窗口
window =tk.Tk()
# 设置回调函数
def callback():
print ("click me!")
# 使用按钮控件调用函数
b = tk.Button(window, text="点击执行回调函数", command=callback).pack()
# 显示窗口
tk.mainloop()
Button 控件的常营属性如下所示:
属性 | 说明 |
---|---|
anchor | 控制文本所在的位置,默认为中心位置(CENTER) |
activebackground | 当鼠标放在按钮上时候,按妞的背景颜色 |
activeforeground | 当鼠标放在按钮上时候,按钮的前景色 |
bd | 按钮边框的大小,默认为 2 个像素 |
bg | 按钮的背景色 |
command | 用来执行按钮关联的回调函数。当按钮被点击时,执行该函数 |
fg | 按钮的前景色 |
font | 按钮文本的字体样样式 |
height | 按钮的高度 |
highlightcolor | 按钮控件高亮处要显示的颜色 |
image | 按钮上要显示的图片 |
justify | 按钮显示多行文本时,用来指定文本的对齐方式,参数值有 LEFT/RIGHT/CENTER |
padx/pady | padx 指定 x 轴(水平方向)的间距大小,pady 则表示 y轴(垂直方向)的间距大小 |
ipadx/ipady | ipadx 指标签文字与标签容器之间的横向距离;ipady 则表示标签文字与标签容器之间的纵向距离 |
state | 设置按钮的可用状态,可选参数有NORMAL/ACTIVE/DISABLED,默认为 NORMAL |
text | 按钮控件要显示的文本 |
除了 Button 按钮之外,和其类似的按钮还有复选框按钮(Checkbutton)和单选框按钮(Radiobutton),它们分别有着不同语法和使用场景,后续会做详细介绍。
下面通过一组示例对 Button 控件的用法做简单的说明:
import tkinter as tk
from tkinter import messagebox
window = tk.Tk()
# 设置窗口的标题
window.title('C语言中文网')
# 设置并调整窗口的大小、位置
window.geometry('400x300+300+200')
# 当按钮被点击的时候执行click_button()函数
def click_button():
# 使用消息对话框控件,showinfo()表示温馨提示
messagebox.showinfo(title='温馨提示', message='欢迎使用C语言中文网')
# 点击按钮时执行的函数
button = tk.Button(window,text='点击前往',bg='#7CCD7C',width=20, height=5,command=click_button).pack()
# 显示窗口
window.mainloop()
程序运行结果如下:
图1:tkinter Button控件
通过上述示例不难看出,Button 控件的作用就是“执行一个函数”,当用户点击按钮时会弹出一个新的对话框,这种操作巧妙地提升了用户的人机交互体验。因此,按钮控件在 GUI 编程中被广泛的使用。
下面为 Button 控件添加一张背景图片,实现代码如下所示:
import tkinter as tk
from tkinter import messagebox
window = tk.Tk()
# 设置窗口的标题
window.title('C语言中文网')
# 设置窗口的大小
window.geometry('400x300+300+200')
# 当按钮被点击的时候执行click\_button()函数
def click\_button():
# 使用消息对话框控件,showinfo()表示温馨提示
messagebox.showinfo(title='温馨提示', message='欢迎使用C语言中文网')
# 创建图片对象
im = tk.PhotoImage(file='C:/Users/Administrator/Desktop/按钮.gif')
# 通过image参数传递图片对象
button = tk.Button(window,image=im,command=click_button).pack()
# 启动窗口
window.mainloop()
程序运行结果如下:
图2:tkinter Button按钮
扩展:按钮的布局
按钮在主窗口中的布局,通常使用 grid() 函数来完成,该函数以网格状的形式(即行和列)来管理窗口的布局。
grid() 布局管理器提供了一个sticky
参数,通过该参数可以设置按钮的方位,该参数默认将控件设置居中,其他参数值有 N/S/W/E(上/下/左/右),而且可以组合在一起使用,比如 NW/WE/SE/SW/NE 等,这与anchor
参数控制文本的显示位置,有着异曲同工之妙。如下图所示:
图3:按钮方位
值得大家注意的是 grid() 布局方法不能与 pack() 混合在一起使用,相关知识在后续内容中还会做针对性讲解。
下面看一组简单的示例:
import tkinter as tk
from tkinter import messagebox
win = tk.Tk()
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x200+100+100')
win.resizable(0,0)
# 将俩个标签分别布置在第一行、第二行
tk.Label(win, text="账号:").grid(row=0)
tk.Label(win, text="密码:").grid(row=1)
# 创建输入框控件
e1 = tk.Entry(win)
# 以 \* 的形式显示密码
e2 = tk.Entry(win,show='\*')
e1.grid(row=0, column=1, padx=10, pady=5)
e2.grid(row=1, column=1, padx=10, pady=5)
# 编写一个简单的回调函数
def login():
messagebox.showinfo('欢迎您到来')
# 使用 grid()的函数来布局,并控制按钮的显示位置
tk.Button(win, text="登录", width=10, command=login).grid(row=3, column=0, sticky="w", padx=10, pady=5)
tk.Button(win, text="退出", width=10, command=win.quit).grid(row=3, column=1, sticky="e", padx=10, pady=5)
win.mainloop()
程序运行结果:
图4:控制按钮位置
Tkinter Entry输入控件
Entry 控件是 Tkinter GUI 编程中的基础控件之一,它的作用就是允许用户输入内容,从而实现 GUI 程序与用户的交互,比如当用户登录软件时,输入用户名和密码,此时就需要使用 Entry 控件。
Entry 控件使用起来非常简单,下面对该控件做简单的介绍。基本语法格式如下:
tk_entry = Entry( master, option, ... )
基本属性
Entry 控件除了具备一些共有属性之外,还有一些自身的特殊属性,如下表所示:
属性名称 | 说明 |
---|---|
exportselection | 默认情况下,如果在输入框中选中文本会复制到粘贴板,如果要忽略这个功能,可以设置为 exportselection=0 |
selectbackground | 选中文字时的背景颜色 |
selectforeground | 选中文字时的前景色 |
show | 指定文本框内容以何种样式的字符显示,比如密码可以将值设为 show=“*” |
textvariable | 输入框内值,也称动态字符串,使用 StringVar() 对象来设置,而 text 为静态字符串对象 |
xscrollcommand | 设置输入框内容滚动条,当输入的内容大于输入框的宽度时使用户 |
1) 动态数据类型
上述表格中提及了 StringVar() 方法,和其同类的方法还有 BooleanVar()、DoubleVar()、IntVar() 方法,不难看出他们分别代表一种数据类型,即字符串、布尔值、浮点型、整型,这些方法并不属于 Python 内置方法,而是 Tkinter 特有的方法。
在界面编程的过程中,有时我们需要“动态跟踪”一些变量值的变化,从而保证值的变换及时的反映到显示界面上,但是 Python 内置的数据类型是无法这一目的的,因此使用了 Tcl 内置的对象,我们把这些方法创建的数据类型称为“动态类型”,比如 StringVar() 创建的字符串,称为“动态字符串”。
下面通过一个时钟示例对“动态字符串”做进一步了解,代码如下:
import tkinter as tk
import time
root = tk.Tk()
root.title("C语言中文网")
root.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
root.geometry('450x150+100+100')
root.resizable(0,0)
root.title('我们的时钟')
# 获取时间的函数
def gettime():
# 获取当前时间
dstr.set(time.strftime("%H:%M:%S"))
# 每隔 1s 调用一次 gettime()函数来获取时间
root.after(1000, gettime)
# 生成动态字符串
dstr = tk.StringVar()
# 利用 textvariable 来实现文本变化
lb = tk.Label(root,textvariable=dstr,fg='green',font=("微软雅黑",85))
lb.pack()
# 调用生成时间的函数
gettime()
# 显示窗口
root.mainloop()
程序运行结果如下:
图1:动态时钟实现
常用方法
除了一些基本的属性之外,Entry 控件还提供了一些常用的方法,如下所示:
方法 | 说明 |
---|---|
delete() | 根据索引值删除输入框内的值 |
get() | 获取输入框内的是 |
set() | 设置输入框内的值 |
insert() | 在指定的位置插入字符串 |
index() | 返回指定的索引值 |
select_clear() | 取消选中状态 |
select_adujst() | 确保输入框中选中的范围包含 index 参数所指定的字符,选中指定索引和光标所在位置之前的字符 |
select_from (index) | 设置一个新的选中范围,通过索引值 index 来设置 |
select_present() | 返回输入框是否有处于选中状态的文本,如果有则返回 true,否则返回 false。 |
select_to() | 选中指定索引与光标之间的所有值 |
select_range() | 选中指定索引与光标之间的所有值,参数值为 start,end,要求 start 必须小于 end。 |
注意:在 Entry 控件中,我们可以通过以下方式来指定字符的所在位置:
- 数字索引:表示从 0 开始的索引数字;
- “ANCHOE”:在存在字符的情况下,它对应第一个被选中的字符;
- “END”:对应已存在文本中的最后一个位置;
- "insert(index,‘字符’):将字符插入到 index 指定的索引位置。
示例如下:
import tkinter as tk
win = tk.Tk()
# 设置主窗口
win.geometry('250x100')
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.resizable(0,0)
# 创建输入框控件
entry1 = tk.Entry(win)
# 放置输入框,并设置位置
entry1.pack(padx=20, pady=20)
entry1.delete(0, "end")
# 插入默认文本
entry1.insert(0,'C语言中文网,网址:c.biancheng.net')
# 得到输入框字符串
print(entry1.get())
# 删除所有字符
# entry1.delete(0, tk.END)
win.mainloop()
程序运行结果:
图2:Entry控件
认识完 Entry 控件的基本属性和常用方法后,下面我看一组简单的示例:
import tkinter as tk
win =tk.Tk()
# 设置主窗口
win.geometry('250x100')
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.resizable(0,0)
# 新建文本标签
labe1 = tk.Label(win,text="账号:")
labe2 = tk.Label(win,text="密码:")
# grid()控件布局管理器,以行、列的形式对控件进行布局,后续会做详细介绍
labe1.grid(row=0)
labe2.grid(row=1)
# 为上面的文本标签,创建两个输入框控件
entry1 = tk.Entry(win)
entry2 = tk.Entry(win)
# 对控件进行布局管理,放在文本标签的后面
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
# 显示主窗口
win.mainloop()
程序运行结果:
图3:tkinter Entry控件
注意:从上述运行结果可以看出,GUI 界面可以说真的很“简陋”,其实一款界面美观的 GUI 程序会受到诸多因素影响,比如距离调整、样式设置等等
Entry控件验证功能
Entry 控件也提供了对输入内容的验证功能,比如要求输入英文字母,你却输入了数字,这就属于非法输入,Entry 控件通过以下参数实现对内容的校验:
参数 | 说明 |
---|---|
validate | 指定验证方式,字符串参数,参数值有 focus、focusin、focusout、key、all、none。 |
validatecommand | 指定用户自定义的验证函数,该函数只能返回 True 或者 Fasle |
invalidcommand | 当 validatecommand 指定的验证函数返回 False 时,可以使用该参数值再指定一个验证函数。 |
下面对 validate 的参数值做简单的介绍:
参数值 | 说明 |
---|---|
focus | 当 Entry 组件获得或失去焦点的时候验证 |
focusin | 当 Entry 组件获得焦点的时候验证 |
focuson | 当 Entry 组件失去焦点的时候验证 |
key | 当输入框被编辑的时候验证 |
all | 当出现上边任何一种情况的时候验证 |
none | 默认不启用验证功能,需要注意的是这里是字符串的 ‘none’ |
下面看一组具体的运行示例:
import tkinter as tk
from tkinter import messagebox
win = tk.Tk()
# 设置主窗口
win.geometry('250x200+250+200')
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.resizable(0,0)
# 创建验证函数
def check():
if entry1.get() == "C语言中文网":
messagebox.showinfo("输入正确")
return True
else:
messagebox.showwarning("输入不正确")
entry1.delete(0,tk.END)
return False
# 新建文本标签
labe1 = tk.Label(win,text="账号:")
labe2 = tk.Label(win,text="密码:")
labe1.grid(row=0)
labe2.grid(row=1)
# 创建动字符串
Dy_String = tk.StringVar()
# 使用验证参数 validata,参数值为 focusout 当失去焦点的时候,验证输入框内容是否正确
entry1 = tk.Entry(win,textvariable =Dy_String,validate ="focusout",validatecommand=check)
entry2 = tk.Entry(win)
# 对控件进行布局管理,放在文本标签的后面
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
win.mainloop()
运行结果如下:
图4:tkinter Entry控件
不仅如此,Tkinter 还为验证函数提供可一些额外的选项,不过想要使用这些额外选项,需要提前使用 register() 方法对验证函数进行注册,。常用的选项如下所示:
选项 | 说明 |
---|---|
%d | 有 3 个参数值,其中 0 表示删除操作;1 表示插入操作;2 表示获得、失去焦点或 textvariable 变量的值被修改导 |
%i | 当用户进行插入或者删除操作的时,该选项不爱哦是插入或者删除的索引位置,若是其他的情况则选项值为 -1 |
%P | 该选项值指定了输入框内的文本内容,只有当输入框的值允许改变的时候,该选项值才会生效。 |
%s | 改值为调用验证函数钱输入框内的文本内容 |
%S | 该选项值,只有插入或者删除操作触发验证函数的时候才会生效,它表示了被删除或者插入的内容 |
%v | 表示当前 Entry 控件的 validate 参数的值 |
%V | 表示触发验证函数的原因,值为 focus、focusin 、focusout、all、key… 中的一个。 |
%W | 该选项表示控件类型,即控件的名字(Entry) |
下面看一组见简单的示例应用:
import tkinter as tk
from tkinter import messagebox
win = tk.Tk()
# 设置主窗口
win.geometry('250x200+250+200')
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.resizable(0,0)
# 新建文本标签
labe1 = tk.Label(win,text="账号:")
labe2 = tk.Label(win,text="密码:")
labe1.grid(row=0)
labe2.grid(row=1)
# 创建动字符串
Dy_String = tk.StringVar()
# 创建验证函数
def check(strings,reason, id):
if entry1.get() == "C语言中文网":
messagebox.showinfo("输入正确")
print(strings,reason,id)
return True
else:
messagebox.showwarning("输入不正确")
print(strings,reason,id)
return False
# 对验证函数进行注册
CheckTest = win.register(check)
# 使用验证参数 validata,参数值为 focusout 当失去焦点的时验证输入框内容是否正确
entry1 = tk.Entry(win,textvariable =Dy_String,validate ="focusout",validatecommand=(CheckTest,'%P','%V','%W'))
entry2 = tk.Entry(win)
# 对控件进行布局管理,放在文本标签的后面
entry1.grid(row=0, column=1)
entry2.grid(row=1, column=1)
win.mainloop()
程序输出结果:
C语言中文网 focusout .!entry
C focusout .!entry
实例演示
下面看一组实例演示,通过实现一个简单的计算器小程序来对 Entry 控件做进一步说明:
from tkinter import *
# 创建窗体
win = Tk()
win.title("C语言中文网")
win.geometry('300x300')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 创建一个容器来包括其他控件
frame = Frame (win)
# 创建一个计算器
def calc() :
# 用户输入的表达式,计算结果后转换为字符串
result = "= "+ str (eval(expression.get()))
#将计算的结果显示在Label控件上
label.config(text =result)
#创建一个Label控件
label = Label (frame)
#创建一个Entry控件
entry = Entry (frame)
#读取用户输入的表达式
expression = StringVar ()
#将用户输入的表达式显示在Entry控件上
entry ["textvariable"] = expression
#创建-一个 Button控件.当用户输入完毕后,单击此按钮即计算表达式的结果
button1 = Button (frame, text="等 于",command=calc)
#设置Entry控件为焦点所在
entry.focus ()
frame.pack ()
#Entry控件位于窗体的上方
entry .pack()
#Label控件位于窗体的左方
label .pack (side="left")
#Button控件位于窗体的右方
button1.pack (side="right")
#开始程序循环
frame .mainloop()
程序运行结果,如下所示:
图5:tkinter Entry控件
Spinbox 高级输入框
Spinbox 是 Entry 控件的升级版,它是 Tkinter 8.4 版本后新增的控件,该控件不仅允许用户直接输入内容,还支持用户使用微调选择器(即上下按钮调节器)来输入内容。在一般情况下,Spinbox 控件用于在固定的范围内选取一个值的时候使用。下面看一组简单的应用示例:
import tkinter as tk
root = tk.Tk()
root.title("C语言中文网")
root.geometry('300x200+300+300')
root.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 如果是数字使用 from_和to参数,范围 0-20,并且与2步长递增或递减
w = tk.Spinbox(root,from_=0,to=20, increment=2,width = 15,bg='#9BCD9B')
w.pack()
# 显示窗口
root.mainloop()
程序运行结果:
图6:Spinbox高级输入控件
若不是数字,而是字符串形式的选项值,则采用values
参数以元组的形式进行传参,如下所示:
import tkinter as tk
root = tk.Tk()
root.title("C语言中文网")
root.geometry('300x200+300+300')
root.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 使用 values 参数以元组的形式进行传参
strings = tk.Spinbox(root,values=('Python','java','C语言','PHP'))
strings.pack()
# 开启事件循环
root.mainloop()
程序运行结果:
图7:Spinbox高级输入框
Tkinter Text文本框控件
xt 文本控件是 Tkinter 中经常使用的控件,与 Entry 控件相比,Text 控件用于显示和编辑多行文本,而 Entry 控件则适合处理单行文本。
Text 控件类似 HTML 中的<textarea>
标签,允许用户以不同的样式、属性来显示和编辑文本,它可以包含纯文本或者格式化文本,同时支持嵌入图片、显示超链接以及带有 CSS 格式的 HTML 等。Text 控件的有很多的适用场景,比如显示某个产品的详细信息,或者人物介绍等。下面我们对 Text 控件属性和常用方法做简单的介绍。
基本属性
除了基本的共有属性之外,Text 控件还具备以下属性:
属性 | 说明 |
---|---|
autoseparators | 默认为 True,表示执行撤销操作时是否自动插入一个“分隔符”(其作用是用于分隔操作记录) |
exportselection | 默认值为 True,表示被选中的文本是否可以被复制到剪切板,若是 False 则表示不允许。 |
insertbackground | 设置插入光标的颜色,默认为 BLACK |
insertborderwidth | 设置插入光标的边框宽度,默认值为 0 |
insertofftime | 该选项控制光标的闪烁频频率(灭的状态) |
insertontime | 该选项控制光标的闪烁频频率(亮的状态) |
selectbackground | 指定被选中文本的背景颜色,默认由系统决定 |
selectborderwidth | 指定被选中文本的背景颜色,默认值是0 |
selectforeground | 指定被选中文本的字体颜色,默认值由系统指定 |
setgrid | 默认值是 False,指定一个布尔类型的值,确定是否启用网格控制 |
spacing1 | 指定 Text 控件文本块中每一行与上方的空白间隔,注意忽略自动换行,且默认值为 0。 |
spacing2 | 指定 Text 控件文本块中自动换行的各行间的空白间隔,忽略换行符,默认值为0 |
spacing3 | 指定 Text 组件文本中每一行与下方的空白间隔,忽略自动换行,默认值是 0 |
tabs | 定制 Tag 所描述的文本块中 Tab 按键的功能,默认被定义为 8 个字符宽度,比如 tabs=(‘1c’, ‘2c’, ‘8c’) 表示前 3 个 Tab 宽度分别为 1厘米,2厘米,8厘米。 |
undo | 该参数默认为 False,表示关闭 Text 控件的“撤销”功能,若为 True 则表示开启 |
wrap | 该参数用来设置当一行文本的长度超过 width 选项设置的宽度时,是否自动换行,参数值 none(不自动换行)、char(按字符自动换行)、word(按单词自动换行) |
xscrollcommand | 该参数与 Scrollbar 相关联,表示沿水平方向上下滑动 |
yscrollcommand | 该参数与 Scrollbar 相关联,表示沿垂直方向左右滑动 |
基本方法
Text 中的方法有几十个之多,这里不进行一一列举,主要对常用的方法进行介绍,如下表所示:
方法 | 说明 |
---|---|
bbox(index) | 返回指定索引的字符的边界框,返回值是一个 4 元组,格式为(x,y,width,height) |
edit_modified() | 该方法用于查询和设置 modified 标志(该标标志用于追踪 Text 组件的内容是否发生变化) |
edit_redo() | “恢复”上一次的“撤销”操作,如果设置 undo 选项为 False,则该方法无效。 |
edit_separator() | 插入一个“分隔符”到存放操作记录的栈中,用于表示已经完成一次完整的操作,如果设置 undo 选项为 False,则该方法无效。 |
get(index1, index2) | 返回特定位置的字符,或者一个范围内的文字。 |
image_cget(index, option) | 返回 index 参数指定的嵌入 image 对象的 option 选项的值,如果给定的位置没有嵌入 image 对象,则抛出 TclError 异常 |
image_create() | 在 index 参数指定的位置嵌入一个 image 对象,该 image 对象必须是 Tkinter 的 PhotoImage 或 BitmapImage 实例。 |
insert(index, text) | 在 index 参数指定的位置插入字符串,第一个参数也可以设置为 INSERT,表示在光标处插入,END 表示在末尾处插入。 |
delete(startindex [, endindex]) | 删除特定位置的字符,或者一个范围内的文字。 |
see(index) | 如果指定索引位置的文字是可见的,则返回 True,否则返回 False。 |
下面先看一组简单的实例介绍,实例如下所示:
from tkinter import *
win = Tk()
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x420')
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = Text(win, width=50, height=30, undo=True, autoseparators=False)
# 适用 pack(fill=X) 可以设置文本域的填充模式。比如 X表示沿水平方向填充,Y表示沿垂直方向填充,BOTH表示沿水平、垂直方向填充
text.pack()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'C语言中文网,一个有温度的网站')
win.mainloop()
程序运行结果:
图1:tkinter text控件
上述代码中 Text 控件通过 heigt 和 width 参数来控制文本域的大小(即纸张大小),当然您也可以将其设置为自适用模式,即不设置具体的文本域大小。
下面定义上述代码做一下稍微改动,为其增加“撤销”和“恢复”的功能,代码如下所示:
from tkinter import *
win = Tk()
win.title("C语言中文网")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x300')
# 创建一个文本控件
# width 一行可见的字符数;height 显示的行数
text = Text(win, width=50, height=20, undo=True, autoseparators=False)
text.grid()
# INSERT 光标处插入;END 末尾处插入
text.insert(INSERT, 'C语言中文网,一个有温度的网站')
# 定义撤销和恢复方法,调用edit_undo()和 edit_redo()方法
def backout():
text.edit_undo()
def regain():
text.edit_redo()
# 定义撤销和恢复按钮
Button(win,text = '撤销',command = backout).grid(row=3, column=0, sticky="w", padx=10, pady=5)
Button(win,text = '恢复',command = regain).grid(row=3, column=0, sticky="e", padx=10, pady=5)
win.mainloop()
程序运行结果:
图2:tkinter Text控件
注意:点击“撤销”按钮后输入的所有语句都会被删除,如果再点击“恢复”按钮,刚刚删除的内容又会恢复。
文本控件(Text)支持三种类型的特殊结构,即 Mark、Tag 以及 Index,每一种结构都有相应的方法,下面对这些结构做相关的介绍。
Index文本索引
Index 索引,用于指定字符在文本中的真实位置,这与我们经常使用 Python 索引是一样的,不过在 Text 文本控件中,两者之间的使用形式存在一些差异。
Tkinter 提供以下文本索引类型,如下表所示:
索引类型 | 说明 |
---|---|
INSERT | 对应插入光标的位置 |
CURRENT | 对应与鼠标坐标最接近的位置 |
END | 对应 Text 控件的文本域中最后一个字符的下一个位置 |
“line.column” | 表示某一行某一列的一个位置,比如 1.2 表示第一行第二列的一个位置 |
“line.end” | 表示某一行到末尾的最后一个位置 |
SEL | 一种针对于 Tag 的特殊索引用法,(SEL_FIRST,SEL_LAST) 表示当前被选中的范围 |
下面看一组示例了解 Index 的使用方法:
from tkinter import *
root = Tk()
root.title("C语言中文网")
root.geometry('400x200')
root.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
text =Text(root, width=35, heigh=15)
text.pack()
# 在文本域中插入文字
text.insert(INSERT, 'C语言中文网')
# 继续向后插入文字
text.insert("insert", ",I love Python")
# 获取字符,使用get() 方法
print(text.get("1.3", "1.end"))
# 显示窗口
root.mainloop()
输出结果如下:
中文网,I love Python
程序显示结果如下:
图3:Tkinter文本控件
Tag文本标签
Tag(标签)用来给一定范围内的文字起一个标签名,通过该标签名就能操控某一范围内的文字,比如修改文本的字体、尺寸和颜色。除此之外,该标签还可以和事件函数绑定在一起使用。
这里需要注意,Tags 的名字是由字符串组成的,但不能是空白字符串。
Tag 提供了一些常用的方法,通过这些方法可以操作 Tag(标签),常用方法如下:
方法 | 说明 |
---|---|
tag_add(tagName,index1,index2) | 为指定索引范围内的内容添加一个标签名字,如果 index2 不存在,则单独为 Index1 指定的内容添加 Tag |
tag_bind(tagName, sequence, func, add=None) | 为 Tag 绑定事件,解除绑定使用 tag_unbind() 方法 |
tag_cget(tagName,option) | 返回 tagName 指定的 option 选项的值 |
tag_configure(tagName, cnf=None, **kw) | 设置 tagName 的选项 |
tag_delete(tagNames) | 删除单个或者多个 tagNames 指定的标签 |
tag_lower(tagName, belowThis=None) | 降低 Tag 的优先级,如果 belowThis 参数不为空,则表示 tagName 需要比 belowThis 指定的 Tag 优先级更低 |
tag_names(index=None) | 如果不带参数,表示返回 Text 组件中所有 Tags 的名字,若存在 index 参数则返回该位置上所有 Tags 的名字 |
tag_nextrange(tagName, index1, index2=None) | 在 index1 到 index2 的范围内第一个 tagName 的位置,若不存在则返回空字符串。 |
tag_raise(tagName, aboveThis=None) | 提高 Tag 的优先级,如果 aboveThis 参数不为空,则表示 tagName 需要比 aboveThis 指定的 Tag 优先级更高 |
tag_ranges(tagName) | 返回所有 tagName 指定的文本,并将它们的范围以列表的形式返回 |
tag_remove(tagName, index1, index2=None) | 删除 index1 到 index2 之间所有的 tagName,如果忽略 index2 参数,那么只删除 index1 指定字符的 tagName |
下面针对上述属性和方法看一组简单的示例:
from tkinter import *
# 创建多行文本框控件
from tkinter import *
# 创建主窗口
win = Tk()
win.title(string = "C语言中文网")
# 创建一个Text控件
text = Text (win)
# 在Text控件内插入- -段文字 ,INSERT表示在光标处插入,END表示在末尾处插入
text.insert (INSERT, "C语言中文网(网址:c.biancheng.net),一个有温度的网站,一生只做一件事\n\n")
# 跳下一行
text.insert (INSERT, "\n\n")
# 在Text控件内插入- -个按钮
button = Button(text, text="关闭",command=win.quit)
text. window_create (END, window=button)
# 填充水平和垂直方向,这里设置 expand为 True 否则不能垂直方向延展
text .pack (fill=BOTH,expand=True)
# 在第一行文字的第0个字符到第6个字符处插入标签,标签名称为"name"
text.tag_add("name", "1.0", "1.6")
# 将插入的按钮设置其标签名为"button"
text.tag_add ("button", button)
#使用 tag_config() 来改变标签"name"的前景与背景颜色,并加下画线,通过标签控制字符的样式
text.tag_config("name", font=('微软雅黑',18,'bold'),background="yellow", foreground= "blue",underline=1)
#设置标签"button"的居中排列
text. tag_config("button", justify="center")
#开始程序循环
win .mainloop()
程序运行结果如下:
图4:tkinter Text控件
Mark文本标记
Mark(标记)通常被用来当作书签,它可以帮助用户快速找到内容的指定位置,并且跟随相应的字符一起移动。
Mark 有两种类型的标记,分别是“INSERT”和“CURRENT”,其含义如下:
- INSERT:指定当前插入光标的位置,Tkinter 会在该位置绘制一个闪烁的光标;
- CURRENT:用于指定当前光标所处坐标最邻近的位置。
它们是 Tkinter 中预定义的标记,因此不能被删除。除此上述标记外,我们还可以通过 user-define marks(用户自定义标记) 的方式来自定义 Mark。Tkinter 也提供了一些有关 Mark 的常用的方法,如下所示:
方法 | 说明 |
---|---|
mark_gravity(markName, direction=None) | 设置 Mark 的移动方向,默认是 “right”,也可以设置为 “left” ,表示即如果在 Mark 处插入文本的话,Mark 的标记移动方向,也就是文本的插入方向。 |
mark_names() | 返回 Text 组件中所有 Marks 的名字 |
mark_next(index) | 返回在 index 指定的位置后边的一个 Mark 的名字 |
mark_previous(index) | 返回在 index 指定的位置前边的一个 Mark 的名字 |
mark_set(markName, index) | 移动 Mark 到 index 参数指定的位置,如果 markName 参数指定的 Mark 不存在,则创建一个新的 Mark |
mark_unset(MarkName) | 删除指定的 Mark |
注意:如果在 Mark 标记的位置之前插入或删除文本,那么 Mark 跟着一起移动。如果要删除 Mark 需要使用 mark_unset() 方法,但是只会删除 Mark 周围的文本,并不会删除 Mark 标记本身。
下面看一组简单的实例:
import tkinter as tk
root = tk.Tk()
root.title("C语言中文网")
root.geometry('400x200')
root.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
text = tk.Text(root, width=35, heigh=15)
text.pack()
text.insert("insert", "C语言中文网")
# 设置标记,这里的 1.end 表示 第一行最后一个字符,当然也可以使用数字来表示比如 1.5 表示第一行第五个字符
text.mark_set("name", "1.end")
# 在标记之后插入相应的文字
text.insert("name", ",网址:c.biancheng.net")
# 跟着自动移动,往后插入,而不是停留在原位置
text.insert("name", ",欢迎光临")
# 若使用 mark_unset() 可以删除指定的标记
# text.mark_unset("name")
# 但使用delete来清楚所有的内容, mark 标记依旧会存在
# text.delete("1.0","end")
# 依然可以使用 name标记来插入
# text.insert("name", "Python答疑")
# 显示窗口
root.mainloop()
程序的运行的结果如下:
图5:Text控件Mark标记
Tkinter列表框和组合框控件详解
列表框(Listbox)和复选框(Combobox)是 Tkinter 中两个控件,由于其非常相似,本节将它们放在一起进行介绍。
Listbox控件
首先介绍一下列表框,即 Listbox。在使用 Tkinter 进行 GUI 编程的过程中,如果需要用户自己进行选择时就可以使用列表框控件。列表框中的选项可以是多个条目,也可以是单个唯一条目,但常用于多个条目。
下面对列表框控件(Listbox)的常用方法做简单的介绍:
方法 | 说明 |
---|---|
activate(index) | 将给定索引号对应的选项激活,即文本下方画一条下划线 |
bbox(index) | 返回给定索引号对应的选项的边框,返回值是一个以像素为单位的 4 元祖表示边框:(xoffset, yoffset, width, height), xoffset 和 yoffset 表示距离左上角的偏移位置 |
curselection() | 返回一个元组,包含被选中的选项序号(从 0 开始) |
delete(first, last=None) | 删除参数 first 到 last 范围内(包含 first 和 last)的所有选项 |
get(first, last=None) | 返回一个元组,包含参数 first 到 last 范围内(包含 first 和 last)的所有选项的文本 |
index(index) | 返回与 index 参数相应选项的序号 |
itemcget(index, option) | 获得 index 参数指定的项目对应的选项(由 option 参数指定) |
itemconfig(index, **options) | 设置 index 参数指定的项目对应的选项(由可变参数 **option 指定) |
nearest(y) | 返回与给定参数 y 在垂直坐标上最接近的项目的序号 |
selection_set(first, last=None) | 设置参数 first 到 last 范围内(包含 first 和 last)选项为选中状态,使用 selection_includes(序号) 可以判断选项是否被选中。 |
size() | 返回 Listbox 组件中选项的数量 |
xview(*args) | 该方法用于在水平方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现。 如果第一个参数是 “moveto”,则第二个参数表示滚动到指定的位置:0.0 表示最左端,1.0 表示最右端;如果第一个参数是 “scroll”,则第二个参数表示滚动的数量,第三个参数表示滚动的单位(可以是 “units” 或 “pages”),例如:xview(“scroll”, 2, “pages”)表示向右滚动二行。 |
yview(*args) | 该方法用于在垂直方向上滚动 Listbox 组件的内容,一般通过绑定 Scollbar 组件的 command 选项来实现 |
除了共有属性之外,列表框控件也有一些其他属性,如下表所示:
属性 | 说明 |
---|---|
listvariable | 1. 指向一个 StringVar 类型的变量,该变量存放 Listbox 中所有的项目 2. 在 StringVar 类型的变量中,用空格分隔每个项目,例如 var.set(“c c++ java python”) |
selectbackground | 1. 指定当某个项目被选中的时候背景颜色,默认值由系统指定 |
selectborderwidth | 1. 指定当某个项目被选中的时候边框的宽度 2. 默认是由 selectbackground 指定的颜色填充,没有边框 3. 如果设置了此选项,Listbox 的每一项会相应变大,被选中项为 “raised” 样式 |
selectforeground | 1. 指定当某个项目被选中的时候文本颜色,默认值由系统指定 |
selectmode | 1. 决定选择的模式,tk 提供了四种不同的选择模式,分别是:“single”(单选)、“browse”(也是单选,但拖动鼠标或通过方向键可以直接改变选项)、“multiple”(多选)和 “extended”(也是多选,但需要同时按住 Shift 键或 Ctrl 键或拖拽鼠标实现),默认是 “browse” |
setgrid | 指定一个布尔类型的值,决定是否启用网格控制,默认值是 False |
takefocus | 指定该组件是否接受输入焦点(用户可以通过 tab 键将焦点转移上来),默认值是 True |
xscrollcommand | 为 Listbox 组件添加一条水平滚动条,将此选项与 Scrollbar 组件相关联即可 |
yscrollcommand | 为 Listbox 组件添加一条垂直滚动条,将此选项与 Scrollbar 组件相关联即可 |
1) 创建列表框控件
下面看一组简单的示例,并对 Listbox 控件做进一步讲解,首先创建一个列表框控件:
# 创建一个列表控件,并增加相应的选项
from tkinter import *
# 创建主窗口
win = Tk()
win.title("C语言中文网")
win.geometry('400x200')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 创建列表选项
listbox1 =Listbox(win)
listbox1.pack()
# i表示索引值,item 表示值,根据索引值的位置依次插入
for i,item in enumerate(["C","C++","C#","Python","Java"]):
listbox1.insert(i,item)
# 显示窗口
win.mainloop()
程序运行结果如下所示:
图1:Listbox列表框控件
除了上述使用 enumerate() 来实现选项插入的方法外,我们还可以使用 “end” 实现,它表示将选项插入到最后一个位置,所以“Java”一定会被插入到最后一个位置上,而之前的选项会依次向前排列,如下所示:
from tkinter import *
# 创建主窗口
win = Tk()
win.title("C语言中文网")
win.geometry('400x200')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 创建列表选项
listbox1 =Listbox(win)
listbox1.pack()
# i表示索引值,item 表示值,根据索引值的位置依次插入
for item in ["C","C++","C#","Python","Java"]:
listbox1.insert("end",item)
# 显示窗口
win.mainloop()
程序运行结果:
图2:tkinter Listbox控件
2) 增加滚动条和删除功能
下面为上述示例增加一个滚动条和选项的删除功能,如下所示:
from tkinter import *
# 创建主窗口
win = Tk()
win.title("C语言中文网")
win.geometry('400x180')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 创建滚动条
s = Scrollbar(win)
# 设置垂直滚动条显示的位置,使得滚动条,靠右侧;通过 fill 沿着 Y 轴填充
s.pack(side = RIGHT,fill = Y)
# 将 selectmode 设置为多选模式,并为Listbox控件添加滚动条
listbox1 =Listbox(win,selectmode = MULTIPLE,height =5, yscrollcommand = s.set)
# i 表示索引值,item 表示值,根据索引值的位置依次插入
for i,item in enumerate(range(1,50)):
listbox1.insert(i,item)
listbox1.pack()
# 设置滚动条,使用 yview使其在垂直方向上滚动 Listbox 组件的内容,通过绑定 Scollbar 组件的 command 参数实现
s.config(command = listbox1.yview)
# 使用匿名函数,创建删除函数,点击删除按钮,会删除选项
bt = Button(win,text='删除',command = lambda x = listbox1:x.delete(ACTIVE))
# 将按钮放置在底部
bt.pack(side = BOTTOM)
# 显示窗口
win.mainloop()
程序运行结果,如下所示:
图3:tkinter listbox控件
3) StringVar() 添加列表选项
下面演示如何通过 StringVar() 方法动态地获取列表框中的选项,示例代码如下:
import tkinter as tk
from tkinter import messagebox
window = tk.Tk()
window.title("C语言中文网")
window.geometry('400x180')
window.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 创建变量,用var1用来接收鼠标点击的具体选项内容
var1 = tk.StringVar()
l = tk.Label(window, bg='#B0B0B0', font=('微软雅黑', 15), width=20, textvariable=var1)
l.pack()
# 创建一个按钮的点击事件
def click_button():
# 使用 curselection来选中文本
try:
val = lb.get(lb.curselection())
# 设置label值
var1.set(val)
except Exception as e:
e = '发现一个错误'
messagebox.showwarning(e,'没有选择任何条目')
# 创建一个按钮并放置,点击按钮调用print_selection函数
b1 = tk.Button(window, text='获取当前选项', command=click_button)
b1.pack()
# 创建Listbox并为其添加内容
var2 = tk.StringVar()
var2.set(("C语言辅导班", "Python答疑辅导", "Java答疑辅导", "C++辅导"))
# 创建Listbox,通过 listvariable来传递变量
lb = tk.Listbox(window, listvariable=var2)
# 新建一个序列,然后将值循环添加到Listbox控件中
items = ["C", "Java", "Python", "C#", "Golang", "Runby"]
for i in items:
lb.insert('end', i) # 从最后一个位置开始加入值
lb.insert(0, '编程学习') # 在第一个位置插入一段字符串
lb.delete(4) # 删除第2个位置处的索引
lb.pack()
#主窗显示
window.mainloop()
程序运行结果如下:
图4:tkinter Listbox控件
Combobox控件
通过前面内容的介绍我们知道 Listbox 是一个供用户从列表项中选择相应条目的控件。但在有些情况下,比如列表的项目过多时,若使用列表控件,列出所有选项就会显得界面格外臃肿,这时就需要用到 Combobox 控件,也就是下拉菜单控件(或称复合框),该控件是列表控件的改进版,具有更加灵活的界面,因此其应用场景相比于前者要更加广泛。
不过需要注意的是 Combobox 并不包含在 tkinter 模块中,而是包含在tkinter.ttk
子模块中,因此若想使用 Combobox 控件,需要使用下面的导包方式:
from tkinter import ttk
下面对 Combobox 控件做简单的介绍,其语法格式如下所示:
cbox=Combobox(窗口对象,[参数列表])
Combobox 控件在形式虽然与列表控件存在不同,但它们的本质是相同,因此属性和方法是通用的。
对于 Combobox 控件而言,它常用的方法有两个,分别是 get() 和 current(),前者表示获取当前选中选项的内容,后者表示获取选中选项的索引值。下面通过一组简单的示例进一步了解 Combobox 控件,示例代码如下:
import tkinter
from tkinter import ttk # 导入ttk模块,下拉菜单控件位于ttk子模块中
# 创建窗口
win = tkinter.Tk()
win.title("C语言中文网")
# win.geometry('400x200')
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x250')
win.resizable(0,0)
# 创建下拉菜单
cbox = ttk.Combobox(win)
# 使用 grid() 来控制控件的位置
cbox.grid(row = 1, sticky="NW")
# 设置下拉菜单中的值
cbox['value'] = ('C','C#','Go','Python','Java')
#通过 current() 设置下拉菜单选项的默认值
cbox.current(3)
# 编写回调函数,绑定执行事件,向文本插入选中文本
def func(event):
text.insert('insert',cbox.get()+"\n")
# 绑定下拉菜单事件
cbox.bind("<<ComboboxSelected>>",func)
# 新建文本框
text = tkinter.Text(win)
# 布局
text.grid(pady = 5)
win.mainloop()
程序运行结果:
图5:tkinter Combobox控件
Tkinter单选框和多选框按钮
单选框按钮控件(Radiobutton),同样允许用户选择具体的选项值,不过与 Listbox 相比,单选按钮控件仅允许用户选择单一的选项值,各个选项值之间是互斥的关系,因此只有一个选项可以被用户选择。
Radiobutton 控件通常都是成组出现的,所有控件都使用相同的变量。Radiobutton 可以包含文本或图像,每一个按钮都可以与一个 Python 函数相关联。当按钮被按下时,对应的函数会被执行。这里需要注意的是,单选按钮控件仅能显示单一字体的文本,但文本可以跨越多行,除此之外,您还可以为个别的字符添加下划线。
Radiobutton 除常用的共有属性之外,还具有一些其他属性,如下表所示:
属性 | 说明 |
---|---|
activebackground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的背景色,默认值由系统指定 |
activeforeground | 设置当 Radiobutton 处于活动状态(通过 state 选项设置状态)的前景色,默认值由系统指定 |
compound | 1. 默认值为 None,控制 Radiobutton 中文本和图像的混合模式,默认情况下,如果有指定位图或图片,则不显示文本 2. 如果该选项设置为 “center”,文本显示在图像上(文本重叠图像) 3. 设置为 “bottom”,“left”,“right” 或 “top”,那么图像显示在文本的旁边,比如如"bottom",则显示图像在文本的下方。 |
disabledforeground | 指定当 Radiobutton 不可用的时的前景色颜色,默认由系统指定 |
indicatoron | 1. 该参数表示选项前面的小圆圈是否被绘制,默认为 True,即绘制; 2. 如果设置为 False,则会改变单选按钮的样式,当点击时按钮会变成 “sunken”(凹陷),再次点击变为 “raised”(凸起) |
selectcolor | 设置当 Radiobutton 为选中状态的时候显示的图片;如果没有指定 image 选项,该选项被忽略 |
takefocus | 如果是 True,该组件接受输入焦点,默认为 False |
variable | 表示与 Radiobutton 控件关联的变量,注意同一组中的所有按钮的 variable 选项应该都指向同一个变量,通过将该变量与 value 选项值对比,可以判断用户选中了哪个按钮。 |
Radiobutton 控件的常用方法如下所示:
方法 | 说明 |
---|---|
deselect() | 取消该按钮的选中状态 |
flash() | 刷新 Radiobutton 控件,该方法将重绘 Radiobutton控件若干次(即在"active" 和 “normal” 状态间切换) |
invoke() | 1. 调用 Radiobutton 中 command 参数指定的函数,并返回函数的返回值 2. 如果 Radiobutton 控件的 state(状态) 是 “disabled” (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Radiobutton 控件设置为选中状态 |
Radiobutton 控件用来解决多选一的问题,它通常是成组出现的,下面看一组简答的示例:
import tkinter as tk
window = tk.Tk()
window.title("C语言中文网")
window.geometry('400x180')
window.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
# 根据单选按钮的 value 值来选择相应的选项
v.set(0)
# 使用 variable 参数来关联 IntVar() 的变量 v
tk.Radiobutton(window, text="C语言中文网", fg='blue',font=('微软雅黑','12','bold'),variable=v, value=0).pack(anchor = 'w')
tk.Radiobutton(window, text="CSDN平台", variable=v, value=2).pack(anchor = 'w')
tk.Radiobutton(window, text="知乎平台", variable=v, value=3).pack(anchor = 'w')
tk.Radiobutton(window, text="牛客网平台", variable=v, value=4).pack(anchor = 'w')
# 显示窗口
window.mainloop()
程序运行结果如下:
图1:tkinter Radiobutton控件
上述代码是比较直接的写法,虽然编码过程简单,但是从代码重构的角度来讲,它是比较冗余的,因此我们推荐下面这种写法,如下所示:
import tkinter as tk
window = tk.Tk()
window.title("C语言中文网")
window.geometry('400x180')
window.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
site = [('美团外卖',1),
('饿了么外卖',2),
('美团闪购',3),
('艾奇外卖',4)]
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
# 重构后的写法,也非常简单易懂
for name, num in site:
radio_button = tk.Radiobutton(window,text = name, variable = v,value =num)
radio_button.pack(anchor ='w')
# 显示窗口
window.mainloop()
程序运行结果如下:
图2:tkinter Radioburron控件
对上述代码稍作修改,当点击某一按钮时,获取选项的内容,代码如下:
import tkinter as tk
def select():
dict = {1:'C语言中文网',2:'菜鸟教程',3:'W3SCHOOL',4:'微学苑'}
strings = '您选择了' + dict.get(v.get()) + ',祝您学习愉快'
lable.config(text = strings)
window = tk.Tk()
window.title("C语言中文网")
window.geometry('400x180')
window.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
lable = tk.Label(window,font=('微软雅黑', '15','bold'),fg='#43CD80')
lable.pack(side ='bottom')
site = [('C语言中文网',1),
('菜鸟教程',2),
('W3SCHOOL',3),
('微学苑',4)]
# IntVar() 用于处理整数类型的变量
v = tk.IntVar()
for name, num in site:
radio_button = tk.Radiobutton(window,text = name, variable = v,value =num,command = select,indicatoron = False)
radio_button.pack(anchor ='w')
# 显示窗口
window.mainloop()
程序运行结果如下:
图3:单选按钮控件
Checkbutton复选框控件
Checkbutton 控件是一种供用户选择相应条目的按钮控件,但与 Radiobutton 不同的是,Checkbutton 控件不仅允许用户选择一项,还允许用户同时选择多项,各个选项之间属于并列的关系。
复选框控件同样有许多适用场景,比如选择兴趣爱好、选择选修课,以及购买多个物品等,在这种情况下都可以使用复选框控件,其语法格式如下:
Checkbutton(master=None, **options)
复选框控件,除了具有常用的共有属性之外,还具有一些其他重要属性和常用方法,下面对它们做简单地介绍:
属性 | 说明 |
---|---|
text | 显示的文本,使用 “\n” 来对文本进行换行。 |
variable | 1. 和复选框按钮关联的变量,该变量值会随着用户选择行为来改变(选或不选),即在 onvalue 和 offvalue 设置值之间切换,这些操作由系统自动完成 2. 在默认情况下,variable 选项设置为 1 表示选中状态,反之则为 0,表示不选中。 |
onvalue | 通过设置 onvalue 的值来自定义选中状态的值。 |
offvalue | 通过设置 offvalue 的值来自定义未选中状态的值。 |
indicatoron | 默认为 True,表示是否绘制用来选择的选项的小方块,当设置为 False 时,会改变原有按钮的样式,与单选按钮相同 |
selectcolor | 选择框的颜色(即小方块的颜色),默认由系统指定 |
selectimage | 设置当 Checkbutton 为选中状态的时候显示的图片,若如果没有指定 image 选项,该选项被忽略 |
textvariable | Checkbutton 显示 Tkinter 变量(通常是一个 StringVar 变量)的内容,如果变量被修改,Checkbutton 的文本会自动更新 |
wraplength | 表示复选框文本应该被分成多少行,该选项指定每行的长度,单位是屏幕单元,默认值为 0 |
下面看一组简单的示例,创建一组复选框控件,代码如下:
from tkinter import *
win = Tk()
win.title("C语言中文网")
win.geometry('500x200')
win.resizable(0,0)
lb = Label(text='C语言中文网答疑辅导班',font=('微软雅黑', 18,'bold'),fg='#CD7054')
lb.pack()
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 新建整型变量
CheckVar1 = IntVar()
CheckVar2 = IntVar()
CheckVar3 = IntVar()
# 设置三个复选框控件,使用variable参数来接收变量
check1 = Checkbutton(win, text="Python",font=('微软雅黑', 15,'bold'),variable = CheckVar1,onvalue=1,offvalue=0)
check2 = Checkbutton(win, text="C语言",font=('微软雅黑', 15,'bold'),variable = CheckVar2,onvalue=1,offvalue=0)
check3 = Checkbutton(win, text="Java",font=('微软雅黑', 15,'bold'),variable = CheckVar3,onvalue=1,offvalue=0)
# 选择第一个为默认选项
# check1.select ()
check1.pack (side = LEFT)
check2.pack (side = LEFT)
check3.pack (side = LEFT)
# 定义执行函数
def study():
# 没有选择任何项目的情况下
if (CheckVar1.get() == 0 and CheckVar2.get() == 0 and CheckVar3.get() == 0):
s = '您还没选择任语言'
else:
s1 = "Python" if CheckVar1.get() == 1 else ""
s2 = "C语言" if CheckVar2.get() == 1 else ""
s3 = "Java" if CheckVar3.get() == 1 else ""
s = "您选择了%s %s %s" % (s1, s2, s3)
#设置标签lb2的字体
lb2.config(text=s)
btn = Button(win,text="选好了",bg='#BEBEBE',command=study)
btn.pack(side = LEFT)
# 该标签,用来显示选择的文本
lb2 = Label(win,text='',bg ='#9BCD9B',font=('微软雅黑', 11,'bold'),width = 5,height=2)
lb2.pack(side = BOTTOM, fill = X)
# 显示窗口
win.mainloop()
程序运行结果如下:
图4:复选框控件
复选框控件提供以下常用方法,如下表所示:
方法 | 属性 |
---|---|
desellect() | 取消 Checkbutton 组件的选中状态,也就是设置 variable 为 offvalue |
flash() | 刷新 Checkbutton 组件,对其进行重绘操作,即将前景色与背景色互换从而产生闪烁的效果。 |
invoke() | 1. 调用 Checkbutton 中 command 选项指定的函数或方法,并返回函数的返回值 2. 如果 Checkbutton 的state(状态)"disabled"是 (不可用)或没有指定 command 选项,则该方法无效 |
select() | 将 Checkbutton 组件设置为选中状态,也就是设置 variable 为 onvalue |
toggle() | 改变复选框的状态,如果复选框现在状态是 on,就改成 off,反之亦然 |
下面看一组简答的示例,如下所示:
from tkinter import *
win = Tk()
win.title("C语言中文网")
win.geometry('500x200')
win.resizable(0,0)
lb = Label(text='C语言中文网答疑辅导班',font=('微软雅黑', 18,'bold'),fg='#CD7054')
lb.pack()
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
# 设置三个复选框控件,
check1 = Checkbutton(win, text="Python",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0)
check2 = Checkbutton(win, text="C语言",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0)
check3 = Checkbutton(win, text="Java",font=('微软雅黑', 15,'bold'),onvalue=1,offvalue=0)
# 将第一个 复选框按钮的 variable值,设置为 onvalue =1 ,表示选中状态
check1.select ()
# 取消了第一个复选框的选中状态
check1.toggle()
check1.pack (side = LEFT)
check2.pack (side = LEFT)
check3.pack (side = LEFT)
# 显示窗口
win.mainloop()
程序运行结果如下:
图5:tkinter复选框控件
Tkinter Scale控件详解
Scale 控件,即滑块控件或标尺控件,该控件可以创建一个类似于标尺式的滑动条对象,用户通过操作它可以直接设置相应的数值(刻度值)。
Scale 控件同样有许多应用场景,并且在我们日常工作中也会经常用到,比如电脑上调节音量的滑动条(数值范围 0-100),如下图所示:
图1:音量控件面板
Scale 控件常用的基本属性如下所示:
参数 | 说明 |
---|---|
activebackground | 指定当鼠标在上方飘过的时候滑块的背景颜色 |
bigincrement | 1. 设置“大”增长量 2. 该选项设置增长量的大小 3. 默认值是 0,增长量为范围的 1/10 |
borderwidth | 1. 指定边框宽度 2. 默认值是 2 |
command | 1. 指定一个函数,每当滑块发生改变的时候都会自动调用该函数 2. 该函数有一个唯一的参数,就是最新的滑块位置 3. 如果滑块快速地移动,函数可能无法获得每一个位置,但一定会获得滑块停下时的最终位置 |
digits | 1. 设置最多显示多少位数字 2. 补充注释:例如设置 from 选项为 0,to 选项为 20,digits 选项设置为 5,那么滑块的范围就是在 0.000 ~ 20.000 直接滑动 3. 默认值是 0(不开启) |
font | 1. 指定滑块左侧的 Label 和刻度的文字字体 2. 默认值由系统指定 |
from_ | 1. 设置滑块最顶(左)端的位置 2. 默认值是 0 |
highlightcolor | 1. 指定当 Scale 获得焦点的时候高亮边框的颜色 2. 默认值由系统指定 |
label | 1. 你可以在垂直的 Scale 组件的顶端右侧(水平的话是左端上方)显示一个文本标签 2. 默认值是不显示标签 |
length | 1. Scale 组件的长度,默认值是 100 像素 |
orient | 1. 设置 Scale 控件是水平放置(HORIZONTAL)还是垂直放置(VERTICAL) 2. 默认值是 VERTICAL(垂直放置) |
repeatdelay | 1. 该选项指定鼠标左键点击滚动条凹槽的响应时间 2. 默认值是 300(毫秒) |
repeatinterval | 1. 该选项指定鼠标左键紧按滚动条凹槽时的响应间隔 2. 默认值是 100(毫秒) |
resolution | 1. 指定 Scale 组件的分辨率(每点击一下移动的步长) 示例: 比如 resolution 选项设置为 0.1 的话,那么每点击一下鼠标就是在 0.0 ~ 20.0 之间以 0.1 的步长移动 2. 该参数的默认值是 1 |
showvalue | 1. 设置是否显示滑块旁边的数字 2. 默认值为 True |
sliderlength | 1. 设置滑块的长度 2. 默认值是 30 像素 |
state | 1. 默认情况下 Scale 组件支持鼠标事件和键盘事件,可以通过设置该选项为 DISABLED 来禁用此功能 2. 默认值是 NORMAL |
takefocus | 1. 指定使用 Tab 键是否可以将焦点移动到该 Scale 组件上 2. 默认是开启的,可以通过将该选项设置为 False 避免焦点落在此组件上 |
tickinterval | 1. 设置显示的刻度,如果设置一个值,那么就会按照该值的倍数显示刻度 2. 默认值是不显示刻度 |
to | 1. 设置滑块最底(右)端的位置 2. 默认值是 100 |
troughcolor | 1. 设置凹槽的颜色 2. 默认值由系统指定 |
variable | 1. 指定一个与 Scale 组件相关联的 Tkinter 变量,该变量存放滑块最新的位置 2. 当滑块移动的时候,该变量的值也会发生相应的变化 |
width | 1. 指定 Scale 组件的宽度 2. 默认值是 15 像素 |
Scale 常用方法有如下四个,见下表所示:
方法 | 说明 |
---|---|
coords(value=None) | 1. 获得当前滑块位置相对于 Scale 控件左上角位置的相对坐标, 2. 如果设置了 value 值,则返回当滑块位于该位置时与左上角的相对坐标 |
get() | 获得当前滑块的位置(即当前数值),返回值可以为整型或者浮点型 |
identify(x, y) | 返回一个字符串表示指定位置下的 Scale 控件 |
set(value) | 设置 Scale 控件的值,即滑块的位置,默认为初始位置 |
下面看一组简单的实例应用:创建一个 Scale 控件
from tkinter import *
# 创建主窗口
win =Tk()
win.title("控制管理界面")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x250')
# 添加一个 Scale 控件,默认垂直方向,步长设置为 5,长度为200,滑动块的大小为 50,最后使用label参数文本
s=Scale(win, from_ =100, to =0,resolution =5,length =200,sliderlength= 20,label ='音量控制' )
s.pack()
# 设置滑块的位置
s.set(value=15)
# 显示窗口
mainloop()
程序运行结果如下:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
gits 选项设置为 5,那么滑块的范围就是在 0.000 ~ 20.000 直接滑动 3. 默认值是 0(不开启) |
| font | 1. 指定滑块左侧的 Label 和刻度的文字字体 2. 默认值由系统指定 |
| from_ | 1. 设置滑块最顶(左)端的位置 2. 默认值是 0 |
| highlightcolor | 1. 指定当 Scale 获得焦点的时候高亮边框的颜色 2. 默认值由系统指定 |
| label | 1. 你可以在垂直的 Scale 组件的顶端右侧(水平的话是左端上方)显示一个文本标签 2. 默认值是不显示标签 |
| length | 1. Scale 组件的长度,默认值是 100 像素 |
| orient | 1. 设置 Scale 控件是水平放置(HORIZONTAL)还是垂直放置(VERTICAL) 2. 默认值是 VERTICAL(垂直放置) |
| repeatdelay | 1. 该选项指定鼠标左键点击滚动条凹槽的响应时间 2. 默认值是 300(毫秒) |
| repeatinterval | 1. 该选项指定鼠标左键紧按滚动条凹槽时的响应间隔 2. 默认值是 100(毫秒) |
| resolution | 1. 指定 Scale 组件的分辨率(每点击一下移动的步长) 示例: 比如 resolution 选项设置为 0.1 的话,那么每点击一下鼠标就是在 0.0 ~ 20.0 之间以 0.1 的步长移动 2. 该参数的默认值是 1 |
| showvalue | 1. 设置是否显示滑块旁边的数字 2. 默认值为 True |
| sliderlength | 1. 设置滑块的长度 2. 默认值是 30 像素 |
| state | 1. 默认情况下 Scale 组件支持鼠标事件和键盘事件,可以通过设置该选项为 DISABLED 来禁用此功能 2. 默认值是 NORMAL |
| takefocus | 1. 指定使用 Tab 键是否可以将焦点移动到该 Scale 组件上 2. 默认是开启的,可以通过将该选项设置为 False 避免焦点落在此组件上 |
| tickinterval | 1. 设置显示的刻度,如果设置一个值,那么就会按照该值的倍数显示刻度 2. 默认值是不显示刻度 |
| to | 1. 设置滑块最底(右)端的位置 2. 默认值是 100 |
| troughcolor | 1. 设置凹槽的颜色 2. 默认值由系统指定 |
| variable | 1. 指定一个与 Scale 组件相关联的 Tkinter 变量,该变量存放滑块最新的位置 2. 当滑块移动的时候,该变量的值也会发生相应的变化 |
| width | 1. 指定 Scale 组件的宽度 2. 默认值是 15 像素 |
Scale 常用方法有如下四个,见下表所示:
方法 | 说明 |
---|---|
coords(value=None) | 1. 获得当前滑块位置相对于 Scale 控件左上角位置的相对坐标, 2. 如果设置了 value 值,则返回当滑块位于该位置时与左上角的相对坐标 |
get() | 获得当前滑块的位置(即当前数值),返回值可以为整型或者浮点型 |
identify(x, y) | 返回一个字符串表示指定位置下的 Scale 控件 |
set(value) | 设置 Scale 控件的值,即滑块的位置,默认为初始位置 |
下面看一组简单的实例应用:创建一个 Scale 控件
from tkinter import *
# 创建主窗口
win =Tk()
win.title("控制管理界面")
win.iconbitmap('C:/Users/Administrator/Desktop/C语言中文网logo.ico')
win.geometry('400x250')
# 添加一个 Scale 控件,默认垂直方向,步长设置为 5,长度为200,滑动块的大小为 50,最后使用label参数文本
s=Scale(win, from_ =100, to =0,resolution =5,length =200,sliderlength= 20,label ='音量控制' )
s.pack()
# 设置滑块的位置
s.set(value=15)
# 显示窗口
mainloop()
程序运行结果如下:
[外链图片转存中…(img-4ECbR15F-1715744440516)]
[外链图片转存中…(img-PoCyiNFQ-1715744440517)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!