Python GUI Programming Cookbook 第二版第一章中文翻译

Python GUI Programming Cookbook 第二版第一章中文翻译

写在最前面的一些话

我不是科班出身的程序员,仅仅因为喜欢python而读过一些书。
但是我还记得我大学时代学VB的时候,第一课就是创建一个叫“Hello,World”的对话框。那一刻,年少轻狂觉得自己无所不能了。
所以,窃认为“没有对话框的编程都是耍流氓”
但是很可惜,即使非常喜欢python的语言风格,基本上没有书去系统介绍如何创建一个交互界面。
连python量化这种高大上的书,用的都是IDLE去输出结果,正如金玉其中,而外面只是一层简陋的纸盒子。简直太不相配了。
好不容易在网上找到关于Python GUI的书,竟然全英文的也只有三本,看来真的是太不受待见了。
所以,也不确定这种Python GUI会不会是鸡肋,毕竟IDLE可以输出好多结果。
所以,先翻译一章看看反映,如果根本没有人关注,那么估计也就这一章翻译了。如果有人关注,可以考虑再往下翻译。
另外,声明,没有得到作者的授权。就是个人的一点兴趣。

还有,不是科班出身,所以一些术语可能翻译不是很准确,请见谅。若有错误请斧正,QQ:284648397

第一章 创建GUI和添加控件

在这一章,我们开始创建非常有趣的Python交互界面,使用的python版本为3.6,以及之前的版本。我们将讲述下列内容

  • 1.1 创建第一个Python交互界面(GUI,以后python交互界面都缩写为GUI)
  • 1.2 锁定窗口大小的调节
  • 1.3 在GUI上增加一个标签(Label)
  • 1.4 创建按钮,以及更改他们的内容及属性(button)
  • 1.5 文本框控件(Entry)
  • 1.6 一个控件获得焦点,和如何失效控件
  • 1.7 组合框控件(combo box)
  • 1.8 创建复选框,且初始状态不同的复选框(check box)
  • 1.9 利用单选框
  • 1.10 利用卷轴文本控件
  • 1.11 增加几个控件在一个循环中

介绍

在本章中,我们会开发我们第一个GUI,用最少的代码去建立一个GUI。之后会在此GUI上不断增加内容。

在我们的第一个配方中*【因为书叫cookbook,中文叫菜谱,所以书中所有的例子都会被称为配方,o( ̄︶ ̄)o*】*,我们会显示所有的代码。在之后的配方中,只会显示增加的代码。

在本章的最后,我们会创建一个GUI,包括标签,按钮,文本框,组合框,不同状态的复选框,以及信号按钮去更改GUI的背景色。

1.1创建第一个GUI

Python是一个非常强大的编程语言,内嵌tkinter模块,只需要几行代码,我们就能创建出第一个GUI

1.1.1 准备工作

为了创建GUI,一个Python开发环境是必不可少的前提。本书的创建环境是Python 3.6,系统是Windows 10 64位系统,但是有鉴于Python跨平台的语言,本书的代码应该都能运行。
【剩下一大堆就是关于Mac和python2兼容性的问题了,暂且略过,有兴趣请联系我,我直接发给你。】

1.1.2 如何做

以下就是第一个GUI的创建代码

import tkinter as tk #引用tkinter模块
win=tk.Tk() #创建GUI
win.title("Python GUI") #设置GUI的标题
win.mainloop() #开始GUI,这句在所有代码的最下面,表示开始创建窗口了。本例中是这样,之后都是这样。

输出:
Python GUI Programming Cookbook 第二版第一章中文翻译_第1张图片

1.1.3 怎么做到的?

第一行:我们引用tkinter模块,并简化为tk
第二行:利用Tk类(class)创建了一个窗口。并将这个窗口分配给变量win(window的缩写)。
因为Python是一个动态语言,我们不需要在分配前声明变量类型,Python会自动判断并分配类型。所以说Python是一个强大而高效的编程语言。
【我简化了翻译,原本比较长,但是大意就是这样。】
第三行:更改了win变量的属性title,可改变GUI的标题。
第四行:通过mainloop方法开始窗口事件循环。之前的代码创建了窗口并更改了一个属性,但是直到这行代码被执行时,窗口才能真正被我们看到。
这是一个无限循环,我们GUI等待着事件,并返回其命令,例如按钮点击等。这个循环会在我们点击窗口的X时被结束。

1.2 锁定窗口大小的调节

一个GUI默认是可被调节大小的,但可能不符合某些场景设定,因为GUI上面的控件可能由于窗口大小的调节,导致排版不如预期。所以在这一节,我们学习如何阻止窗口被放大或缩小。

1.2.1 准备工作

这次的配方会扩展上一节的代码,所以要求你先把上一节的代码敲进Python哦

1.2.2 如何做

import tkinter as tk #引用tkinter模块
win=tk.Tk() #创建GUI
win.title("Python GUI") #设置GUI的标题

#==========================================
win.resizable(False,False) #使窗口调节失效
#win.resizable(True,False) #使窗口只能调节x轴,调节不了y轴,反之相反。
#==============================================

win.mainloop() #开始GUI

【结果就是调节不了大小了,就不上图了】

1.2.3 如何做到的?

这条代码失效了窗口大小调节,并让最大化按钮灰掉无法使用。
resizable()方法是Tk()类中的一种,传入(False, False),对应(x轴,y轴),使得x轴和y轴都无法调节。任一False变成True,都让对应轴变得可以调节。

1.3 GUI上增加一个标签

标签是GUI上一个很简单的控件,可以去解释其他控件的作用,也可以提供额外的信息。

1.3.1 准备工作

我们正在扩展第一个配方,但是删除了阻止调节大小的代码。

1.3.2 如何做。

import tkinter as tk 
from tkinter import ttk
win=tk.Tk() 
win.title("Python GUI") 

#==========================================
ttk.Label(win,text="A Label").grid(column=0,row=0) #增加一个标签
#==============================================

win.mainloop() #开始GUI

输出如下
在这里插入图片描述

1.3.3 怎么做到的?

首先,我们要从tkinter中引用ttk模块【这个模块可以让我们的GUI更好看】,ttk是themed tk的简称。
然后,利用ttk.Label()函数去增加一个标签。注意,Label第一个字母大写。
grid()在第二章会讲
【不过其实很简单的,就是布局位置】
Python GUI Programming Cookbook 第二版第一章中文翻译_第2张图片
另外,GUI会变得很窄平,因为我们只增加了一个标签,GUI会随着我们增加内容而自动扩展窗口大小,如果更长的标签(字数更多),那么窗口会自己加长。

另外,增加更多的控件,也会自动扩展窗口大小。

1.4 创建按钮,以及更改他们的内容及属性

这一节,我们要增加按钮控件,而且利用这个按钮更改另一个控件的属性。这一节我们会引进回叫功能。
【回叫功能,callback:我们给GUI一个命令,例如点击一个按钮,等待GUI回叫我们,即根据命令进行下一个事件。其实就是点击按钮,然后有反应就是callback】

1.4.1 准备工作

就是1.3中的代码

1.4.2 如何做

import tkinter as tk 
from tkinter import ttk

win=tk.Tk() 
win.title("Python GUI") 
#==========================================
a_label=ttk.Label(win,text="A Label") #增加一个标签——1     
a_label.grid(column=0,row=0) #设定标签的位置——2
#==============================================
#增加按钮点击事件
def click_me():   #——3
	action.configure(text="** I have been Clicked! **")  #——4
	a_label.configure(foreground='red')  #——5
	a_label.configure(text='A Red Label')  #——6

#增加一个按钮
action=ttk.Button(win,text="Click Me!", command=click_me)  #——7
action.grid(column=1,row=0)  #——8
#===============================================
win.mainloop() #开始GUI

初始输出:
在这里插入图片描述
点击了按钮之后的会变成
在这里插入图片描述

1.4.3 怎么做到的?

——1:把标签分配给一个变量a_label
——2:设置标签的位置
——3:更改变量a_label的属性,用click_me()的功能。在默认下,这是模块级别的变量,所以我们可以在函数功能内连接它,只要我们在函数之前声明这个变量就可以了。
——4:设置一个事件,当按钮被点击时触发。
——7:创建了一个按钮,将函数设定的click_me()赋予按钮,用command命令。

GUI是事件驱动,点击一个按钮会创建一个事件,我们用ttk.Button控件中的command属性连接事件发生时什么会发生,用的是回叫功能(callback)。

【谁能告诉我callback在编程中的术语呀,最好能高大上一点,虽然书中解释这就是拨号(点击)——回叫(事件)功能。】
——5:我们也改变了变迁的颜色。
——6&8:使用了grid样式管理,会在第二章讨论。

1.5 文本框控件

在tkinter,典型的一行文本框控件称为Entry(输入)。在这个配方里,我们将添加一个Entry(输入).我们会利用标签使Entry对于用户更加易懂。

1.5.1 准备工作

基于上一节的代码

1.5.2 如何做

#==============================================
#增加按钮点击事件
def click_me():   
	action.configure(text="Hello, "+name.get())  #——1
    
#更改我们的标签
ttk.Label(win,text='Enter a name:').grid(column=0,row=0)  #——2

#增加一个文本框Entry控件
name=tk.StringVar() #S和V必须都大写,不然会报错——3    
name_entered=ttk.Entry(win,width=12,textvariable=name) #——4
name_entered.grid(column=0,row=1)

#增加一个按钮
action=ttk.Button(win,text="Click Me!", command=click_me)  
action.grid(column=1,row=1)  #——5
#===============================================

【只显示了新增或更改的代码】
输出
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.5.3 如何做到的?

——1:我们得到了Entry控件的值,我们现在还没有用OPP(面对对象编程),所以当我们还未声明一个变量的时候,如何能读取这个变量的值呢?
如果不用OPP类,那么我们只能从顺序上,将声明变量的代码放在上面。这是怎么工作的呢?
答案是,当按钮被点击时,是一个回叫功能,也就是在按钮之前声明变量即可,之后会被回叫到函数功能上。

【所以,顺序是click_me()的回叫函数,之后是标签,之后是声明name变量,最后是生成一个按钮。这样的顺序保证了在command被激活之前,name变量已经被声明了,不会出现“name没有定义”这样的报错。】

生活很美好哦【作者的文风就是这样的。】

——2:这行代码执行一个标签,而且就在我们文本框的正上方,这么做可以让我们的Entry更有目的性。用的也是grid方法,第二章会介绍到。

——3&4:创建了一个变量name,这个变量和Entry控件绑定在一起,而在click_me()中,我们通过get()来取得Entry控件的值。就像一个咒语一样。

——4:正如我们所见,输出中,即使输入再多内容,Entry控件不会自行调节宽窄,因为我们硬编码了它的宽度为12。

——5:【按钮是上一节的,但是为了美观,row从0变成1,这样排版更合理,书上没有提,但是他代码里改了】

Python是一个动态语言,如果我们将字符分配给name变量,那么name就是字符类型变量。如果分配了整数,就是整数变量。
在使用tkinter,我们不得不首先声明name是什么样的类型变量,用的命令是,tk.StringVar()。因为tkinter不是python,它无法自己辨别变量类型。

1.6 一个控件获得焦点,和如何失效控件

随着我们的GUI不断改良,它将更加方便快捷,使得GUI出现时,光标就已经出现在Entry控件里。

1.6.1 准备工作

上一节的代码

1.6.2 如何做

Python真的很强大。【全书一直都在赞美Python,顺便踩一脚Java,O(∩_∩)O】我们可以用focus()方法让控件一开始就获得焦点和光标

在上一节代码的最下面写下面一行就可以【在mainloop()的上面哦,mainloop什么时候基本上都是最下面的】

name_entered.focus() 

如果报错,请检查是否有变量声明顺序方面有问题。因为没有用OPP类,顺序很重要。

如果你用的是Mac,获得焦点可能会麻烦一些。

光标一开始就在Entry控件里,且获得焦点,就是最前端的窗口。你马上就可以在Entry里输入字符。

1.6.3 失效控件

#增加一个按钮
action=ttk.Button(win,text="Click Me!", command=click_me)  
action.grid(column=1,row=1)
action.configure(state='disable') #使按钮失效

name_entered.focus()

这样一开,初始化GUI,按钮就失效了。
【如果希望点击之后失效,就把这行代码写在def click_me()的最下面,这样一来,就是点击按钮之后失效。】

1.6.4 如何做到的

这个代码是自我解释的。我们让一个控件获得了焦点,又失效了另一个控件。好的命名规则在编程中可以减少解释的必要。

1.7 组合框控件【combobox下拉选择列表】

在这一节的配方中,我们将添加一个下拉选择列表到GUI上,这个列表已经有默认的值。同时,我们还可以限制用户只能从中选择一个,我们也可以让用户自己键入他们想要的任何值。

1.7.1 准备工作

上一节的代码

1.7.2 如何做

#增加一个文本框Entry控件
name=tk.StringVar() #S和V必须都大写,不然会报错
name_entered=ttk.Entry(win,width=12,textvariable=name)
name_entered.grid(column=0,row=1)

#增加一个按钮
action=ttk.Button(win,text="Click Me!", command=click_me)  
action.grid(column=1,row=1)

ttk.Label(win,text="Choose a number:").grid(column=1, row=0) #——1

number=tk.StringVar() #——2
number_chosen=ttk.Combobox(win, width=12, textvariable=number) #——3
number_chosen['values']=(1,2,3,42,100) #——4
number_chosen.grid(column=1, row=1) 
number_chosen.current(0) #——5

name_entered.focus()
#===============================================
win.mainloop() #开始GUI

Python GUI Programming Cookbook 第二版第一章中文翻译_第3张图片
我们用一个圆括号把默认值传递给了combobox控件,这些值就会出现在下拉菜单中,我们可以随意改变其值。

1.7.3 怎么做到的呢?

——1:增加了第二个标签来匹配我们的combobox控件
——2:声明了一个number变量,指明了其类型。
——3:创建了combobox控件,并将number分配给这个控件。
——4:设置了下拉菜单的默认值,值是字符类型的,因为绑定了number变量,随其类型而来。
——5:设置了初始GUI时,combobox控件所显示的值。
当选择了一个值,这个值可以用number.get()得到。

1.7.4 更多的……

如果我们想限制用户,只从下拉菜单中选择,我们可以用state属性去限制。

number_chosen=ttk.Combobox(win, width=12, textvariable=number, state='readonly') #——3

1.8 复选框,初始状态不同的复选框

在这一节里,我们创造三个初始状态不同的复选框控件

1.8.1 准备工作

需要扩展上节的代码

1.8.2 如何做

我们创造三个初始状态不同的复选框控件。
第一个:已选但灰色失效,用户无法取消勾选
第二个:激活且未选,用户可以通过点击而勾选
第三个:激活且已选,用户可以通过点击而取消勾选。

#创造三个复选框
chVarDis=tk.IntVar()    #——1.1
check1=tk.Checkbutton(win,text="Disabled",variable=chVarDis, state='disabled')  #——1.2
check1.select() #——1.3
check1.grid(column=0,row=4,sticky=tk.W)

chVarUn=tk.IntVar() #——2.1
check2=tk.Checkbutton(win,text="UnChecked", variable=chVarUn)  #——2.2
check2.deselect() #——2.3
check2.grid(column=1, row=4, sticky=tk.W)

chVarEn=tk.IntVar()  #——3.1
check3=tk.Checkbutton(win,text="Enabled",variable=chVarEn)  #——3.2
check3.select() #——3.3
check3.grid(column=2,row=4,sticky=tk.W)

效果如下:
Python GUI Programming Cookbook 第二版第一章中文翻译_第4张图片

1.8.3 怎么做到的

在——1.1、——2.1和——3.1中,我们创建了三个整数类型的变量。在之后每组跟随着三个变量的大妈中,我们创建了一个复选框(Checkbutton),传递给这些变量。他们会控制复选框的状态(勾选或未勾选)。在默认中,0代表未勾选,1为勾选。所以这三个变量是整数变量。

我们将复选框放置在主窗口内,所以在所有——*.2的语句中,第一个变量位置为win,即主窗口的变量名,text属性即复选框后面所显示的文本。

在grid管理中使用sticky属性:tk.W意味着控件会被分配到主窗口的西方(west),即使用户再次调整窗口大小,此控件都只会在最西边,而不会移动到中间去。这点和JAVA很像。

——*.3语句,select()方法是将对号放入复选框中。

grid管理方法第二章会讲到。

1.9 利用单选框

这一节,我们将创建单选框控件,还会增加一些改变主窗口背景颜色的代码。不同的单选框被选择时,会改变不同的颜色。

1.9.1 准备工作

上一节的代码

1.9.2 如何做

#信号按钮——全局  #——1
COLOR1="Blue"
COLOR2="Gold"
COLOR3="Red"

#信号按钮——回叫 #——2
def radCall():
    radSel=radVar.get()
    if radSel==1:
        win.configure(background=COLOR1)
    elif radSel ==2:
        win.configure(background=COLOR2)
    elif radSel ==3:
        win.configure(background=COLOR3)
    
#创造三个信号按钮
radVar=tk.IntVar()  #——3
rad1=tk.Radiobutton(win,text=COLOR1, variable=radVar, value=1, command=radCall)
rad1.grid(column=0, row=5, sticky=tk.W)

rad2=tk.Radiobutton(win,text=COLOR2, variable=radVar, value=2, command=radCall)
rad2.grid(column=1, row=5, sticky=tk.W)

rad3=tk.Radiobutton(win,text=COLOR3, variable=radVar, value=3, command=radCall)
rad3.grid(column=2, row=5, sticky=tk.W)

运行效果:
Python GUI Programming Cookbook 第二版第一章中文翻译_第5张图片

1.9.3 如何做到的

——1的三条代码创建三个全局变量,用来之后创建单选框和更改背景色的回叫函数

我们利用全局变量使其更容易更改代码。相对于搜索-取代的硬编码字符串,这样的全局变量更加符合DRY原则,(Don’t repeat yourself.不要重复自己)。这是一个OPP概念,(面对对象编程)我们之后会用到。

颜色代码需要用到tkinter里的颜色关键字,不然不会起作用。(此处用颜色代码也行,ff开头的那些)

——2:设置一个回叫函数,用来更改主窗口的背景色

——3:我们创建一个tk.IntVar变量,很重要的一点是我们只创建一个变量给三个单选框使用。这样一来,无论用户从主界面上选择哪一个,另外两个都会自动取消选择。

之后的代码:创建三个单选框,位置为主页面win,将变量值传给单选框,单选框利用变量值再传给回叫函数,从而改变了背景色。

【还有两节,这几天一定写完】

你可能感兴趣的:(Python GUI Programming Cookbook 第二版第一章中文翻译)