摘录 python核心编程s

GUI(Graphical User Interface)图形用户界面。

Tcl、Tk和Tkinter

Tkinter是python的默认GUI库。它基于Tk工具包,该工具包最初是为工具命令语言(Tcl)设计的。Tk普及后,被移植到很多其他的脚本语言中,包括Perl(Perl/Tk)、Ruby(Ruby/Tk)和Python(Tkinter)。

安装和使用Tkinter

Tkinter在系统中不是默认必须安装的,可以通过在python解释器中尝试导入Tkinter模块(在Python3中重命名为tkinter)来检查Tkinter是否可用。这里我测试的环境是Python3.6,这里没有发生错误:

>>> import tkinter
>>>

如果失败了的话,就需要重新编译Python解释器以使用tkinter了。

tkinter和Python编程

让GUI程序启动和运行起来需要以下5个步骤:

  1. 导入tkinter模块
  2. 创建一个顶层窗口对象,用于容纳整个GUI应用
  3. 在顶层窗口对象之上构建所有的GUI组件及其功能
  4. 通过底层的应用代码将这些GUI组件连接起来
  5. 进入主事件循环

窗口和控件

在GUI编程中,顶层的根窗口对象包含组成GUI应用的所有的小窗口对象。它们可能是文字标签、按钮、列表框等。这些独立的GUI组件称为控件(widget)。所以当我们说创建一个顶层窗口时,只是表示需要一个地方来摆放所有的控件。一般写成:

top = tkinter.Tk() #或者当采用‘from tkinter import *’ 时,也可直接写成 Tk()

tkinter.Tk()返回的对象通常称为根窗口,这也是一些应用使用root而不是top来指代它的原因。

顶层窗口是那些在应用中独立显示的部分。GUI程序中可以有多个顶层窗口,但是只有一个是根窗口。

控件可以独立存在,也可以作为容器存在。如果一个控件包含其他控件,就可以将其认为是那些控件的父控件。相应的,如果一个控件被其他控件包含,则称这个控件是那个控件的子控件。

事件驱动处理

通常,控件有一些相关的行为,比如按下按钮、将文本写入文本框、敲击回车等。这些行为称为事件。而GUI对这类事件的响应称为回调。

一个GUI程序从开始到结束就是通过整套事件体系来驱动的,这种方式称为事件驱动处理。

比如,最简单的鼠标移动。假设鼠标正停在GUI应用顶层窗口某处,将鼠标移动到另一部分,鼠标移动的行为会被复制到屏幕的光标上,于是看起来像是你的手在移动。系统必须处理的这些鼠标移动事件可以绘制窗口上的指针移动。当释放鼠标时,不再有事件需要处理,此时屏幕会重新恢复闲置的状态。

事件驱动的GUI处理本质上非常适合客户端/服务器架构。当启动一个GUI应用时,需要一些启动步骤来准备核心部分的执行,就像网络服务器启动时必须先分配套接字并将其绑定到本地地址上一样。GUI应用必须先创建所有的GUI组件,然后将他们绘制在屏幕上。这是布局管理器的职责所在。当布局管理器排列好所有空间后,GUI应用进入类似服务器的无限循环。这个循环一直运行,直到出现GUI事件,进行处理。

布局管理器

Tk有3种布局管理器来帮助控件进行定位。最原始的一种称为Placer。他的做法非常直接:你提供控件的大小和位置,然后交给布局管理器。这就存在很大的问题,你必须对所有控件进行这些操作,开发者很大负担。

第二种布局管理器,Packer,也是我们主要是用的。它会把控件填充到正确的位置(即指定的父控件中),然后对于之后的每个控件,回去寻找剩余的空间进行填充。这个处理很像是旅行时往行李箱中填充行李的过程。

第三种布局管理器是Grid。你可以基于网格坐标,使用Grid来指定GUI空间的放置。Grid会在它们的网格位置上渲染GUI应用中的每个对象。

本次学习中我们使用Packer。一旦Packer确定好所有控件的大小和对齐方式,它就会在屏幕上将其位置放置妥当。

当所有的控件摆放好后,可以让应用进入无限主循环中,代码如下:Tkinter.mainloop()

一般来说,这是程序运行的最后一段代码。当进入主循环后,GUI就从这里开始接管程序的执行,所有其他行为都会通过回调来处理,包括退出应用。

顶层窗口:Tkinter.Tk()

之前提到的所有主要控件都是构建在顶层窗口对象之上的,该对象在tkinter中使用Tk类进行创建:

>>> import tkinter
>>> top = tkinter.Tk()

在这个窗口中,可以放置独立的控件,也可以将多个组件拼凑在一起构成GUI程序。下面开始介绍Tk控件

Tk控件

下面介绍了18种Tk控件(更多或者更详细的资料参考Python主站上的Tkinter主题页):

控件 描述
Button 于Label类似,但提供额外的功能,如鼠标悬停、按下、释放以及键盘事件
Canvas 提供绘制形状的选择(线段、椭圆、多边形、矩形),可以包含图像和位图
Checkbutton 一组选框,可以勾选其中的任意个(和HTML中的checkbox类似)
Entry 单行文本框,用于收集键盘输入
Frame 包含其他控件的纯容器
Label 用于包含文本或图像
LabelFrame 标签和框架的组合,拥有额外的标签属性
Listbox 给用户显示一个选项列表进行选择
Menu 按下Menubutton后弹出的选项列表,用户可以从中选择
Menubutton 用于包含菜单(下拉、级联等)
Message 消息,于Label类似,不过可以显示成多行
PanedWindow 一个可以控制其他控件在其中摆放的容器控件
Radiobutton 一组按钮,其中只有一个可以按下
Scale 线型‘滑块’控件,根据已设定的起始值和终止值,给出当前设定的精确值
Scrollbar 为Text、Canvas、Listbox、Enter等支持的控件提供滚动功能
Spinbox Entry和Button的组合,允许对值进行调整
Text 多行文本框,用于收集或显示用户输入的文本
Toplevel 和Frame类似,不过他提供了一个单独的窗口容器

下面先来看看一下简单的使用:

Label控件

下面tkhello.py脚本中,展示了Tkinter应用如何启动,着重强调了Label控件:

#python 3.6

import tkinter

top = tkinter.Tk()#创建顶层窗口
label = tkinter.Label(top,text='Hello world!')#创建标签label,包含连个参数
label.pack()#使用Packer来管理和显示控件
tkinter.mainloop()#运行GUI程序。这是必须的

运行效果:

Button控件

下面的tkhello2.py脚本中,展示了按钮控件:

#python 3.6

import tkinter

top = tkinter.Tk()#创建顶层窗口
quit = tkinter.Button(top,text='Hello World!',command=top.quit)#创建按钮quit,包含三个参数,其中第三个参数给按钮安装了一个回调函数:当按下按钮并释放后,程序就会退出
quit.pack()#使用Packer来管理和显示控件
tkinter.mainloop()#运行GUI程序。这是必须的

运行效果:

Label和Button控件

下面的tkhello3.py脚本中,结合了标签和按钮的功能,并使用了更多的参数:既包括控件的非默认参数,又展示了Packer的一些参数。fill参数告诉Packer让‘退出’按钮占据剩余的水平空间,expand参数则会引导它填充整个水平可视空间,将按钮拉伸到左右窗口边缘。同时,如果Packer没有收到其他指示,所有控件都是垂直排列的(自上而下依次排列):

#python 3.6

import tkinter

top = tkinter.Tk()
hello = tkinter.Label(top,text='Hello Tkinter!') #创建一个标签
hello.pack() quit = tkinter.Button(top,text='退出',command=top.quit,bg='red',fg='white')#创建一个退出按钮,除了绑定一个回调函数外,还设置了背景色以及释放按钮时的颜色
quit.pack(fill = tkinter.X,expand=1)# tkinter.mainloop()

运行效果:

Label、Button和Scale控件

下面的tkhello4.py脚本中,在之前的基础上增加了Scale控件:

#python 3.6
from tkinter import * #虽然这种写法会污染命名空间,但是这里依然使用这种写法是因为该脚本会大量引用此模块 #该函数依附于Scale控件,当Scale控件的滑块移动时,这个函数就会被激活。该函数会调整Label控件中的文本大小
def resize(ev = None):
label.config(font = 'Helvetica -%d bold' % scale.get()) top = Tk()#顶层窗口
top.geometry('250x150+1000+500')#设置顶层窗口的属性,250x150是指窗口大小,1000+500是指窗口在屏幕上的位置 #创建一个Label控件,拥有默认大小的字体
label = Label(top,text = 'hello world!',font = 'Helvetica -12 bold')
label.pack(fill = Y,expand=1)#通过Packer管理和显示label控件
#创建Scale控件,该控件通过回调resize函数用来控制Label控件中字体大小的;from_属性是滑块最小值,to是滑块最大值
scale = Scale(top,from_=10,to=40,orient=HORIZONTAL,command=resize)
scale.set(30)#设置滑块的初始值
scale.pack(fill=Y,expand = 1)#通过Packer管理和显示Scale控件 #创建一个退出按钮控件,按下按钮前的颜色是白色,释放按钮后的颜色是红色
quit = Button(top,text='退出',command=top.quit,activeforeground='white',activebackground='red')
quit.pack()#通过Packer管理和显示Button控件 mainloop()#主循环

运行效果:

tkinter结合偏函数应用实例

何谓偏函数:当函数的参数个数比较多的时候,可以使用functools.partial创建一个新的函数,这个新函数会固定住(冻住)原函数的部分参数,之后,当获得需要的剩余参数后,可以将它们解冻,一起传入到最终的参数中,从而使用最终确定的所有参数去调用函数。简单说就是:。functools.partial会把一个函数的某些参数设置默认值,并返回一个新函数,我们可以直接调用这个新函数。友情链接:偏函数

偏函数的一大优点就是它不局限于函数,而是可以用于任何可调用对象(任何包括函数接口的对象),只需要使用圆括号即可,包括类、方法或可调用实例。

对于很多可调用对象,并且许多调用都反复使用相同参数的情况,使用偏函数会更合适。

GUI编程是一个很好的偏函数用例,因为你很有可能需要GUI控件在外观上具有某种一致性,而这种一致性来自于使用相同参数创建相似的对象时。想象有这么一个应用,有很多按钮拥有相同的背景色和前景色,对于这种只有细微差别的按钮,每次都使用相同的参数创建相同的实例简直是一种负担和浪费。

下面的pfaGUI2.py脚本中,展示了一个交通路标的实例,该应用会尝试创建文字版本的路标,并将其根据标志类型进行区分,比如严重、警告、通知。而标志类型决定了创建时的颜色方案:严重级别的是白底红字,警告级别的是黄底黑字,通知级别的是白底黑字。这里,‘严禁驶入’和‘错误路线’属于严重级别,‘交通拥堵’‘火车交汇口’属于警告级别,而‘限速’和‘单行线’属于通知级别。该应用会创建这些标志的按钮,当用户按下按钮时,会弹出相应的对话框。

这里要注意的版本问题,python2.x中的tkMessageBox模块在python3.x中被重命名为messagebox,并被整合进tkinter模块中:

#python 3.6

from functools import partial#使用偏函数
from tkinter import Tk,X,Button#仅仅导入tkinter模块中用到的属性
from tkinter.messagebox import showinfo,showwarning,showerror #python 3.xb版本中对tkMessageBox重命名。这里仅仅导入三个对话框
#python2.x中使用from tkMessageBox import showinfo,showwarning,showerror #定义了三个标志 警告、严重、通知
WARN = 'warn'
CRIT = 'crit'
REGU = 'regu'
SIGNS = {
'严谨驶入': CRIT,
'火车交汇': WARN,
'限速': REGU,
'错误路线': CRIT,
'交通拥堵': WARN,
'单行线': REGU,
'do not': CRIT
} #对话框用作按钮的回调函数,将在创建每个按钮时使用他们
critCB = lambda:showerror('Error','按下错误按钮')
warnCB = lambda:showwarning('Warning','按下警告按钮')
infoCB = lambda:showinfo('Info','按下通知按钮')
#启动Tk,设置标题、位置
top = Tk()
top.title('路标')
top.geometry('250x250+700+500')#设置顶层窗口的属性,250x250是指窗口大小,1000+500是指窗口在屏幕上的位置
Button(top,text='退出',command = top.quit,bg = 'red',fg = 'white').pack() #创建一个退出按钮。设置前景色、背景色,并用Packer管理 MyButton = partial(Button,top)#创建了一个一阶偏函数,模板化Button类和根窗口top。MyButton效果相当于tkinter.Button() 并将top作为他的第一个参数
#下面是三个二阶偏函数。二阶偏函数是对一阶偏函数的再次模板化。最终效果相当于使用top、回调函数和颜色这几个参数去调用Button。
CritButton = partial(MyButton,command = critCB,bg = 'white',fg = 'red')
WarnButton = partial(MyButton,command = warnCB,bg = 'yellow')
ReguButton = partial(MyButton,command = infoCB,bg = 'white') for eachSign in SIGNS:
signType = SIGNS[eachSign]
#构建一个可求值字符串cmd,该字符串包含按钮名、传给按钮标签的文本参数 和 pack()操作组成。如果是严重级别,会把字符大写,否则按照标题格式输出。这里还使用了三元操作符。格式化字符串的时候要注意%s和%r的区别.
#标题化函数title(),即所有单词的首字母都大写,其他的字母都小写
cmd = '%sButton(text = %r%s).pack(fill = X,expand = True)' % \
(signType.title(),eachSign,'.upper()' if signType ==CRIT else '.title()') #
eval(cmd)#该函数用于执行一个字符串表达式,这里是实例化按钮 top.mainloop()#主循环,用于启动GUI程序

运行效果图:

自此,我们算是入门了。下节我们展示一个中级的tkinter示例~咩

pytho GUI编程之Tkinter的更多相关文章

  1. Python GUI编程之WxPython

    https://en.wikipedia.org/wiki/WxPython 官网: Overview of wxPython: https://wxpython.org/pages/overview ...

  2. Python笔记_第四篇_高阶编程_GUI编程之Tkinter_1.使用Python进行GUI编程的概述

    1. GUI概述: GUI全称为Graphical User Interface,叫做图形用户界面,也是一种交互方式(Interaction).早期计算机使用的命令行界面(command-line i ...

  3. C++混合编程之idlcpp教程Python篇(7)

    上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同 ...

  4. C++混合编程之idlcpp教程Lua篇(7)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件: ...

  5. QT核心编程之Qt线程 (c)

    QT核心编程之Qt线程是本节要介绍的内容,QT核心编程我们要分几个部分来介绍,想参考更多内容,请看末尾的编辑推荐进行详细阅读,先来看本篇内容. Qt对线程提供了支持,它引入了一些基本与平台无关的线程类 ...

  6. Linux应用编程之lseek详解

    Linux应用编程之lseek详解 1.lseek函数介绍 (1).文件指针:当我们要对一个文件进行读写时,一定要先打开这个文件,所以我们读写的所有文件都是动态文件.动态文件在内存中的形态就是文件流的 ...

  7. 网络编程之socket

    网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...

  8. C++混合编程之idlcpp教程Python篇(9)

    上一篇在这 C++混合编程之idlcpp教程Python篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程PythonTutorial7中除了四个文件PythonTu ...

  9. C++混合编程之idlcpp教程Lua篇(9)

    上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.c ...

随机推荐

  1. 【Luogu P3834】可持久化线段树(主席树)

    Luogu P3834 可持久化数据结构就是支持在历史版本上进行查询和修改操作的数据结构. 主席树就是对线段树的改进,使之可持久化. 前置知识:动态开点线段树 我们利用权值(值域)线段树统计区间内的数 ...

  2. 开源WPF控件库MaterialDesignInXAML推荐

    今天介绍一个开源的C# WPF开源控件库,非常漂亮,重点是开源哦 WPF做桌面开发是很有优势的,除了微软自带的控件外,还有很多第三方的控件库,比如收费的Dev Express For WPF.Tele ...

  3. 题解 P3954 【成绩】

    题目评级: ★ (水题) 内容及算法: 无,简单模拟计算即可 代码: /** *@author little_frog */ #include <bits/stdc++.h> using ...

  4. Linux -- 进程间通信几种方式的总结

    管道 优点 管道文件不占磁盘空间,打开管道时在内存中分配空间: 管道读端会在读取完管道内数据后自动进入阻塞,直到写端再次写入数据: 缺点 管道是半双工的,数据只能从一个方向上流动: 管道大小 PIPE ...

  5. Unicode和Ascii的区别

    计算机只能处理数字,如果要处理文本,就必须把文本转换成数字.    最早的计算机设计采用8bit作为一个字节,所以,一个字节只能表示的最大整数255.   0-255被用来表示数字和一些符号,这个编码 ...

  6. CCNA 之 七 路由协议 三 OSPF

    OSPF协议 OSPF开放式最短路径优先 全称:Open Shortest Path First 是目前使用最为广泛的路由协议,主要因为OSPF是开放式协议,和IGRP.EIGRP思科的私有协议不同. ...

  7. windows下python IDE安装注意事项&Python安装及编辑器UliPad安装

    python下载地址: http://www.python.org/download/releases/2.7.6/ 我自己用的是ulipad  ,但是注意  ulipad和python的版本一定要配 ...

  8. Linux发展历史(简略)

    LINUX UNIX历史发展 1969肯 汤姆森在DEC PDP-7机器上开发出了UNIX系统 1971肯 汤姆森的同事丹尼斯 里奇发明了C语言 1973UNIX系统绝大部分用C语言重写,为提高UNI ...

  9. Android DataBinding不能自动生成ViewDataBinding类的解决方法

    如果Build.gradle和Layout文件配置正确,仍无法生成ViewDataBinding类. 经测试,Gradle的sync无效,clean project无效,invalidate and ...

  10. 微服务管理平台nacos虚拟ip负载均衡集群模式搭建

    一.Nacos简介 Nacos是用于微服务管理的平台,其核心功能是服务注册与发现.服务配置管理. Nacos作为服务注册发现组件,可以替换Spring Cloud应用中传统的服务注册于发现组件,如:E ...