您现在的位置是:首页 > 技术教程 正文

python做出软件的界面,python编写的软件界面

admin 阅读: 2024-03-22
后台-插件-广告管理-内容页头部广告(手机)

一、图形界面编程

图形用户界面(Graphical User Interface,GUI)是用户与程序交互的接口,好的GUI会大大提高用户交互体验,其实就是我们平时使用电脑时,使用鼠标、键盘点击的程序界面python实现猴子跳台阶。
Python提供很多创建GUI的程序库,程序员可以选择其中的一个来创建自己的程序界面ai伪原创api,如何用php调用。

  • PyGObject: 基于GObject的C函数库提供了内省绑定,这些库支持GTK+3图形界面工具集,因此PyGObject提供了丰富的图形界面组件。
  • PyGTK:基于老版GTK+2的库(C语言)提供绑定,官方网站。
  • PyQt:Python编程语言和Qt库(C++GUI应用开放框架)的融合,可跨平台使用
  • PySide:Nokia提供的Qt封装,
  • wxPython:以wxWidgets为基础,在不同平台调用不同的本都组件,以符合平台风格。跨平台GUI库,官方网站。

如果读者需要,可以选择任意的GUI库来开发图形界面。如果考虑开发跨平台界面,推荐使用PyQt或wxPython。
本章介绍的GUI库时Tkinter,它是Python自带的GUI库,无需额外下载安装,只要导入tkinter包即可使用。
与其他编程语言的 GUI 工具包相比,Tkinter 编码效率高,能够实现快速开发的目的,非常适合初学者学习。Tkinter 使用纯 Python 语言开发,与 C/C++ 开发的 Qt 框架相比,Tkinter 有自身的局限性,比如性能、功能丰富程度等都不及 Qt,因此它只适合开发一些简单的程序,比如计算器的界面,或者一个简易的聊天窗口等。
学习GUI编程类似于搭建积木的过程,我们也通过这个步骤来讲解:

  1. 了解我们这套积木中都含有哪些积木块(GUI库中包含的组件),都是个什么东西。
  2. 准备一张桌子来作为工作场地(建立程序主窗口)
  3. 将积木拼接在一起(在容器/窗口中对组件布局)
  4. 深入掌握每个积木块的功能和用法(各组件用法,完成工作内容)
    接下来我们将一步一步实现界面编程。

1.1 Tkinter GUI编程组件

其实,Tkinter是一个程序包,里面包含了很多模块,例如Tk、ttk、messagebox等,Tk模块是创建简单界面的主要模块,其中的组件也是继承了object类,下图显示了各组件的继承关系:
在这里插入图片描述
现在我们来了解一下‘积木块’的大体功能,不求完全记住,后面还会有详细讲解。
下表列出了 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 中不同的组件受到各自参数的约束(即参数),所有组件既有相同属性,也有各自独有的属性。本节内容,先对这些组件的共用属性做简单介绍,如下表所示:

属性名称说明单位典型值
background(bg)背景颜色,参数值可以颜色的十六进制数,或者颜色英文单词COLOR‘gray25’或‘#ff4400’
foreground(fg)前景色,也就是字体的颜色,参数值可以颜色的十六进制数,或者颜色英文单词COLOR‘gray25’或‘#ff4400’
activebackground激活状态时的背景色color‘gray25’或‘#ff4400’
activeforeground激活状态时的前景色color‘gray25’或‘#ff4400’
highlightbackground高亮状态时的背景色color‘gray25’或‘#ff4400’
highlightcolor高亮状态时的前景色color‘gray25’或‘#ff4400’
selectbackground选中状态时的背景色color‘gray25’或‘#ff4400’
selecforeground选中状态时的前景色color‘gray25’或‘#ff4400’
disabledforground禁止状态时的前景色color‘gray25’或‘#ff4400’
height该参数值用来设置组件的高度,文本控件以字符的高度(px,font指定),其他控件则以像素为单位px或pixel14
width用于设置控件的宽度,文本控件以字符的高度(px,font指定),其他控件则以像素为单位px或pixel14
borderwidth定于组件的边框宽度pixel2
highlightthickness高亮状态下周围方形区域宽度pixel2
selectborderwidth选中状态时的边框宽度pixel2
relief定义组件的边框样式constantFLAT(平的)/RAISED(凸起的)/SUNKEN(凹陷的)/GROOVE(沟槽桩边缘)/RIDGE(脊状边缘)
image定义显示在组件内的图片文件address
bitmap定义显示在组件内的位图文件,受anchor、justify选项影响,同时指定bitmap、text、image时,可能会覆盖低优先级的选项,优先级关系为image>bitmap>textaddress
text定义控件的标题文字str‘确定’
testcariable指定显示文本的变量variablebnText
font若组件支持设置标题文字,就可以使用此属性来定义,它是一个数组格式的参数 (字体,大小,字体样式)数组‘Helvetica’或(‘Verdana’,8)
anchor定义组件信息(文本或图片)在窗口内的位置N(上)、NE(左上角)、E(右)、SE、S、SW、W、NW、CENTER
justify定义多行文字的对齐方式constantLEFT/CENTER/RIGHT
padx/pady定义组件内的文字或者图片与控件边框之间的水平/垂直距离pixel12
state控制组件是否处于可用状态constant参数值默认为 NORMAL/DISABLED,默认为 NORMAL(正常的)
takefocus组件在键盘遍历(Tab或Shift+Tab)时,是否接收焦点boolean1或Yes(接受);0或No(不接收)
command执行事件函数,比如单击按钮时执行特定的动作,可将执行用户自定义的函数
cursor当鼠标指针移动到组件上时,定义鼠标指针的类型cursorcrosshair(十字光标)、watch(待加载圆圈)、plus(加号)、arrow(箭头)、gumby等
注意:对于上述属性先做大体的了解即可,因为后续章节会对这些控件做更为详细的介绍。

1.2 建立主窗口Tk

主窗口(Tk对象)是一切组件的基础,它好比是一台高速运转的机器,而其他控件则相当于这台机器上的部件,比如齿轮、链条、螺丝等等。由此我们知道,主窗口是一切控件的基础,所有的控件的都需要通过主窗口来显示。
Tkinter 能够很方便地创建一个空白窗口,值得注意的是Python 2.x需要import Tkinter,Python 3.x需要import tkinter。
创建窗口对象可以使用2中方法,

  1. 使用Tk()类创建窗口(此时里面什么都没有,指定了自命名的master主窗口)
  2. 直接创建组件的子类,可以默认初始化一个含有该组件的窗口(使用self.master引用),不建议这么使用。
1.2.1 使用Tk()创建窗口

示例代码如下:

  1. # 导入tk
  2. from tkinter import *
  3. # 创建一个主窗口对象
  4. window = Tk()
  5. # 调用mainloop()显示主窗口
  6. window.mainloop()

程序运行结果如下:
在这里插入图片描述

  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,当用户点击关闭窗口时,窗口不会关闭,而是触发回调函数。

下面通一个示例对上述表格中的常用方法做简单地介绍:

  1. import tkinter as tk
  2. window =tk.Tk()
  3. #设置窗口title
  4. window.title('Python学习')
  5. #设置窗口大小:宽x高,注,此处不能为 "*",必须使用 "x"
  6. window.geometry('450x300')
  7. # 获取电脑屏幕的大小
  8. print("电脑的分辨率是%dx%d"%(window.winfo_screenwidth(),window.winfo_screenheight()))
  9. # 要求窗口的大小,必须先刷新一下屏幕
  10. window.update()
  11. print("窗口的分辨率是%dx%d"%(window.winfo_width(),window.winfo_height()))
  12. # 如使用该函数则窗口不能被拉伸
  13. # window.resizable(0,0)
  14. # 改变背景颜色
  15. window.config(background="#6fb765")
  16. # 设置窗口处于顶层
  17. window.attributes('-topmost',True)
  18. # 设置窗口的透明度
  19. window.attributes('-alpha',1)
  20. # 设置窗口被允许最大调整的范围,与resizble()冲突
  21. window.maxsize(600,600)
  22. # 设置窗口被允许最小调整的范围,与resizble()冲突
  23. window.minsize(50,50)
  24. #更改左上角窗口的的icon图标,加载C语言中文网logo标
  25. window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
  26. #添加文本内容,并对字体添加相应的格式 font(字体,字号,"字体类型")
  27. text=tk.Label(window,text="Python学习,网址:https://editor.csdn.net",bg="yellow",fg="red",font=('Times', 15, 'bold italic underline'))
  28. #将文本内容放置在主窗口内
  29. text.pack()
  30. # 添加按钮,以及按钮的文本,并通过command 参数设置关闭窗口的功能
  31. button=tk.Button(window,text="关闭",command=window.quit)
  32. # 将按钮放置在主窗口内
  33. button.pack(side="bottom")
  34. #进入主循环,显示主窗口
  35. window.mainloop()
  1. protocol协议处理机制
    Tkinter 除了提供事件绑定机制之外,还提供了协议处理机制,它指的是应用程序和窗口管理器之间的交互,最常用的协议为 WM_DELETE_WINDOW。

当 Tkinter 使用 WM_DELETE_WINDOW 协议与主窗口进行交互时,Tkinter 主窗口右上角x号的关闭功能失效,也就是无法通过点击x来关闭窗口,而是转变成调用用户自定义的函数。

下面看一组简单的示例:

  1. from tkinter import Tk
  2. # 导入 对话框控件
  3. from tkinter import messagebox
  4. # 创建主窗口
  5. root = Tk()
  6. # 定义回调函数,当用户点击窗口x退出时,执行用户自定义的函数
  7. def QueryWindow():
  8. # 显示一个警告信息,点击确后,销毁窗口
  9. if messagebox.showwarning("警告","出现了一个错误"):
  10. # 这里必须使用 destory()关闭窗口
  11. root.destroy()
  12. # 使用协议机制与窗口交互,并回调用户自定义的函数
  13. root.protocol('WM_DELETE_WINDOW', QueryWindow)
  14. root.mainloop()

通过封装函数的形式来执行相应的 GUI 控件功能,这在学习 Tkinter 编程的整个过程中非常常见,比如 Button 控件的command参数也可以执行回调函数,如下所示:

  1. import tkinter as tk
  2. # 定义窗口
  3. window = tk.Tk()
  4. window.title('Python学习')
  5. window.geometry('300x300')
  6. window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
  7. # 定义回调函数
  8. def callback():
  9. print("执行回调函数","欢迎学习Python")
  10. # 点击执行按钮
  11. button = tk.Button(window, text="执行", command=callback)
  12. button.pack()
  13. window.mainloop()

设置窗口位置
当我们运行 Tkinter 程序时,主窗口都会出现在距离屏幕左上角指定的位置上,这是由 Tkinter 软件包默认设置的。但是在许多情况下,我们需要根据实际情况来移动窗口在电脑屏幕上的位置,这时应该如何处理呢?其实很简单,通过窗口对象的 geometry() 方法即可改变主窗口的位置,其语法格式如下:

geometry('450x400+300+200')

上述代码表示,设置主窗口的宽度为 450,高度为 400,同时窗口距离左边屏幕的距离为 300(以像素为单位),距离屏幕顶部的距离为 200,这里我们将带“+”的参数值称为“位置参数”,当然,您也可以将它们设置为负数,如下所示:

geometry('+-1500+-2000')

当设置了一个超过屏幕的负参数值时,主窗口会被移动至“屏幕之外”,此时就看不到主窗口了,这也是隐藏窗口的一种方法。

下面看一组简单的示例:

  1. import tkinter as tk
  2. window = tk.Tk()
  3. window.title('Python学习')
  4. window.iconbitmap('C:/Users/Administrator/Desktop/favicon.ico')
  5. # 设置窗口大小变量
  6. width = 300
  7. height = 300
  8. # 窗口居中,获取屏幕尺寸以计算布局参数,使窗口居屏幕中央
  9. screenwidth = window.winfo_screenwidth()
  10. screenheight = window.winfo_screenheight()
  11. size_geo = '%dx%d+%d+%d' % (width, height, (screenwidth-width)/2, (screenheight-height)/2)
  12. window.geometry(size_geo)
  13. window.mainloop()

程序运行后窗口将出现在屏幕的中间位置。

1.2.2 使用组件创建窗口

上一小节我们使用TK()创建了主窗口,然后在Windows主窗口上面创建组件的方式来构建我们的用户接口。还有一种方式就是字节创建组件的子类,子类就会自动创建TK对象作为窗口,例如下面的程序(以Frame为例)

  1. from thinter import *
  2. #定义继承Frame的Application类
  3. class Application(Frame):
  4. def __init__(self,master=None):
  5. Frame.__init__(self,master)
  6. self.pack()
  7. # 调用initWidgets()方法初始化界面
  8. self.initWidgets()
  9. def initWidgets(self):
  10. #创建Lable对象,第一个参数指定将该Lable放入本类(self)中
  11. w = Lable(self)
  12. #创建一个位图
  13. bm = PhotoImage(file = 'serial.png')
  14. #使用一个变量引用图片,避免图片变量无引用时被自动回收
  15. w.x = bm
  16. #设置Lable显示图片
  17. w['image'] = bm
  18. #放入窗口中
  19. w.pack()
  20. # 创建Button对象
  21. okButton = Button(self,text='确定‘)
  22. okButton['background'] = 'yellow'
  23. # okButton.configure(background='yellow') # 与上面代码作用相同
  24. okButton.pack()
  25. #创建Application对象
  26. app = Application()
  27. #组件的master属性值是Tk对象(窗口)
  28. print(type(app.master))
  29. # 通过master属性来设置窗口属性
  30. app.master.title('窗口标题’)
  31. # 启动主窗口消息循环
  32. app.mainloop()

本例直接使用子类创建了组件,并没有直接指定master属性,而是使用了系统自动生成的主窗口。
另外需要学习的内容是组件怎么在窗口中工作的:

  • 创建GUI组件,相当于创建‘积木块’,指定组件属于哪个容器(主窗口,本例使用self,未指定master),
  • 添加GUI组件,此处使用了pack()方法将组件添加到主窗口中
  • 配置GUI组件,实质就是为组件的属性赋值,例如title = ‘窗口标题’

通常配置组件有两个时机:

  • 创建组件时,以关键字方式配置,例如Button(self,text='确定‘)
  • 创建完成后,以字典语法配置,例如okButton[‘background’]=‘yellow’

需要注意的是,每种组件有自己的配置选项,前面我们介绍了组件的一些通用的、常用的属性,特殊属性可以使用帮助文档学习,本处不在介绍,

1.3 组件布局

前面我们介绍了’积木块‘(组件),’拼装桌面‘(主窗口Tk对象),接下来要做的就是将这些组件怎么拼接在一起,也就是积木的组装过程。
一个优秀的图形用户界面,更像是艺术家的作品,它会给用户非常良好的感官体验,因此布局管理不单单是枯燥的程序代码,更需要以“美”的角度去审视每一个细节,这才是学习布局管理的“不二法门”。Tkinter 提供了一系列布局管理的方法和容器控件,通过对这些内容的学习,您将掌握如何使用不同的方法完成界面布局。

1.3.1 布局管理器

Tkinter 提供了三种常用的布局管理器,分别是 pack()、grid() 以及 place(),如下表所示:

方法说明
pack()按照控件的添加顺序其进行排列,遗憾的是此方法灵活性较差
grid()以行和列(网格)形式对控件进行排列,此种方法使用起来较为灵活
place()可以指定组件大小以及摆放位置,三个方法中最为灵活的布局方法

上述三种方法适用于 Tkinter 中的所有控件,在讲解前面内容时,对其中一些方法已经做了相关的介绍。在本节会对上述三个方法的应用场景做更为详细的介绍。

1.3.1.1 pack()布局

pack() 是一种较为简单的布局方法,在不使用任何参数的情况下,它会将控件以添加时的先后顺序,自上而下,一行一行的进行排列,并且默认居中显示。pack() 方法的常用参数如下所示:

属性说明
anchor组件在窗口中的对齐方式,有 9 个方位参数值,比如"n"/“w”/“s”/“e”/“ne”,以及 “center” 等(这里的 e w s n分别代表,东西南北)
expand是否可扩展窗口,参数值为 True(扩展)或者 False(不扩展),默认为 False,若设置为 True,则组件的位置始终位于窗口的中央位置
fill参数值为 X/Y/BOTH/NONE,表示允许控件在水平/垂直/同时在两个方向上进行拉伸,比如当 fill = X 时,控件会占满水平方向上的所有剩余的空间。
ipadx,ipady需要与 fill 参数值共同使用,表示组件的内容和组件边框的距离(内边距),比如文本内容和组件边框的距离,单位为像素§,或者厘米©、英寸(i)
padx,pady用于控制组件之间的上下、左右的距离(外边距),单位为像素§,或者厘米©、英寸(i)
side组件放置在窗口的哪个位置上,参数值 ‘top’,‘bottom’,‘left’,‘right’。注意,单词小写时需要使用字符串格式,若为大写单词则不必使用字符串格式

下面看一组简单的使用示例:

  1. from tkinter import *
  2. win = Tk()
  3. win.title("Python学习")
  4. win.geometry('450x300+300+300')
  5. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. lb_red = Label(win,text="红色",bg="Red",fg='#ffffff',relief=GROOVE)
  7. # 默认以top方式放置
  8. lb_red.pack()
  9. lb_blue = Label(win,text="蓝色",bg="blue",fg='#ffffff',relief=GROOVE)
  10. # 沿着水平方向填充,使用 pady 控制蓝色标签与其他标签的上下距离为 5 个像素
  11. lb_blue.pack(fill=X,pady='5px')
  12. lb_green = Label(win,text="绿色",bg="green",fg='#ffffff',relief=RAISED)
  13. # 将 黄色标签所在区域都填充为黄色,当使用 fill 参数时,必须设置 expand = 1,否则不能生效
  14. lb_green.pack(side=LEFT,expand=1,fill = BOTH)
  15. win.mainloop()
1.3.1.2 grid()布局

grid() 函数是一种基于网格式的布局管理方法,相当于把窗口看成了一张由行和列组成的表格。当使用该 grid 函数进行布局的时,表格内的每个单元格都可以放置一个控件。,从而实现对界面的布局管理。
注意:这里的所说的“表格”是虚拟出来,目的是便于大家理解,其实窗体并不会因为使用了 gird() 函数,而增加一个表格。

grid() 函数的常用参数如下所示:

属性说明
column控件位于表格中的第几列,窗体最左边的为起始列,默认为第 0 列
columnsapn控件实例所跨的列数,默认为 1 列,通过该参数可以合并一行中多个领近单元格。
ipadx,ipady用于控制内边距,在单元格内部,左右、上下方向上填充指定大小的空间。
padx,pady用于控制外边距,在单元格外部,左右、上下方向上填充指定大小的空间。
row控件位于表格中的第几行,窗体最上面为起始行,默认为第 0 行
rowspan控件实例所跨的行数,默认为 1 行,通过该参数可以合并一列中多个领近单元格。
sticky该属性用来设置控件位于单元格那个方位上,参数值和 anchor 相同,若不设置该参数则控件在单元格内居中

grid() 方法相比 pack() 方法来说要更加灵活,以网格的方式对组件进行布局管理,让整个布局显得非常简洁、优雅。如果说非要从三个布局管理器中选择一个使用的话,那么我推荐大家使用 grid() 方法。
这里有一点需要大家要特别注意,在一个程序中不能同时使用 pack() 和 grid() 方法,这两个方法只能二选一,否则程序会运行错误。
下面看一组有关 grid() 函数的简单的示例:

  1. from tkinter import *
  2. #主窗口
  3. win = Tk()
  4. win.config(bg='#87CEEB')
  5. win.title("Python学习")
  6. win.geometry('500x350+300+300')
  7. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  8. #在窗口内创建按钮,以表格的形式依次排列
  9. for i in range (10):
  10. for j in range (10):
  11. Button (win, text=" (" + str(i) + ","+ str(j)+ ")",bg='#D1EEEE') .grid(row=i,column=j)
  12. # 在第5行第11列添加一个Label标签
  13. Label(win,text="Python学习",fg='blue',font=('楷体',12,'bold')).grid(row =4,column=11)
  14. #开始窗口的事件循环
  15. win. mainloop()

当使用 grid 函数布局的时,其实就是为各个控件指定行号、列号的过程,我们不需要为每个单元格指定大小,因为 grid 会为每个单元格自动设置一个适合的尺寸。

下面通过 grid() 布局管理器制作一个简易的登录界面,代码如下所示:

  1. import tkinter as tk
  2. from tkinter import messagebox
  3. root = tk.Tk()
  4. root.title("Python学习")
  5. root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. root.resizable(0,0)
  7. tk.Label(root, text="用户名").grid(row=0, sticky="w")
  8. tk.Label(root, text="密码").grid(row=1, sticky="w")
  9. tk.Entry(root).grid(row=0, column=1)
  10. tk.Entry(root, show="*").grid(row=1, column=1)
  11. # 加载图片LOGO,注意这里是gif格式的图片
  12. photo = tk.PhotoImage(file="C:/Users/Administrator/Desktop/1.gif")
  13. tk.Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx='4px', pady='5px')
  14. # 编写一个简单的回调函数
  15. def login():
  16. messagebox.showinfo('欢迎学习Python')
  17. # 使用grid()函数来布局,并控制按钮的显示位置
  18. tk.Button(root, text="登录", width=10, command=login).grid(row=3, column=0, columnspan=2,sticky="w", padx=10, pady=5)
  19. tk.Button(root, text="退出", width=10, command=root.quit).grid(row=3, column=1, columnspan=2,sticky="e", padx=10, pady=5)
  20. # 开启事件主循环
  21. root.mainloop()
1.3.1.3 place()

与前两种布局方法相比,采用 place() 方法进行布局管理要更加精细化,通过 place() 布局管理器可以直接指定控件在窗体内的绝对位置,或者相对于其他控件定位的相对位置。

下面对 place 布局管理器的常用属性做相关介绍:

属性说明
anchor定义控件在窗体内的方位,参数值N/NE/E/SE/S/SW/W/NW 或 CENTER,默认值是 NW
bordermode定义控件的坐标是否要考虑边界的宽度,参数值为 OUTSIDE(排除边界) 或 INSIDE(包含边界),默认值 INSIDE。
x、y定义控件在根窗体中水平和垂直方向上的起始绝对位置
relx、rely定义控件相对于根窗口(或其他控件)在水平和垂直方向上的相对位置(即位移比例),取值范围再 0.0~1.0 之间; 可设置 in_ 参数项,相对于某个其他控件的位置
height、width控件自身的高度和宽度(单位为像素)
relheight、relwidth控件高度和宽度相对于根窗体高度和宽度的比例,取值也在 0.0~1.0 之间

通过上述描述我们知道,relx和rely参数指定的是控件相对于父组件的位置,而relwidth和relheight参数则是指定控件相对于父组件的尺寸大小。
注意:这里父组件指的是当前可操作控件的上层组件,比如在没有使用容器控件(frame)的窗体中,控件的父组件就是主窗口本身。
上述表格中关于距离位置的参数容易产生“疑惑”,下面通过一组简单的示例来进一步说明:

  1. from tkinter import *
  2. #主窗口
  3. win = Tk()
  4. win.title("Python学习")
  5. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. #创建一个frame窗体对象,用来包裹标签
  7. frame = Frame (win, relief=SUNKEN, borderwidth=2, width=450, height=250)
  8. # 在水平、垂直方向上填充窗体
  9. frame. pack (side=TOP, fill=BOTH, expand=1)
  10. # 创建 "位置1"
  11. Label1 = Label ( frame, text="位置1",bg='blue',fg='white')
  12. # 使用 place,设置第一个标签位于距离窗体左上角的位置(40,40)和其大小(width,height)
  13. # 注意这里(x,y)位置坐标指的是标签左上角的位置(以NW左上角进行绝对定位,默认为NW)
  14. Label1.place (x=40,y=40, width=60, height=30)
  15. # 设置标签2
  16. Label2 = Label (frame, text="位置2",bg='purple',fg='white')
  17. # 以右上角进行绝对值定位,anchor=NE,第二个标签的位置在距离窗体左上角的(180,80)
  18. Label2.place(x=180,y=80, anchor=NE, width=60, height=30)
  19. # 设置标签3
  20. Label3 = Label (frame, text="位置3",bg='green',fg='white')
  21. # 设置水平起始位置相对于窗体水平距离的0.6倍,垂直的绝对距离为80,大小为60,30
  22. Label3.place(relx=0.6,y=80, width=60, height=30)
  23. # 设置标签4
  24. Label4 = Label (frame, text="位置4",bg='gray',fg='white')
  25. # 设置水平起始位置相对于窗体水平距离的0.01倍,垂直的绝对距离为80,并设置高度为窗体高度比例的0.4倍,宽度为80
  26. Label4.place(relx=0.01,y=80,relheight=0.4,width=80)
  27. #开始事件循环
  28. win. mainloop()

注意:在一个父组件中 place()方法可以与 grid() 方法混合使用,要与 pack() 进行区别。

1.3.2 布局管理组件

除了上一节《Tkinter布局管理方法》中提到的三个常用方法外,Tkinter 还提供了几个常用的布局管理控件,比如 Frame 、LabelFrame 等,这些控件的主要作用是为其他控件提供载体,并将主窗口界面划分成多个区域,从而方便开发者对不同区域进行设计与管理。

在前文讲解其他的 Tkinter 控件时,我们列举的大多数示例都是将控件直接放置在主窗口(即根窗口)内,这样做的目的是为了便于大家理解。但在实际的开发过程中,控件一般放置在容器中,比如 Frame 容器控件,如同 HTML 中的

标签一样,把容器看做成一个框架,其他控件则是这个框架中的“元素”。

本节介绍了四种常用的容器控件以及它们的使用方法,分别是 Frame、LabelFrame、PanedWindow 以及 Toplevel。

1.3.2.1 Frame控件

Frame 本质上也是一个矩形窗体,同其他控件一样也需要位于主窗口内。我们可以在主窗口内放置多个 Frame 控件,并且每个 Frame 中还可以嵌套一个或者多个Frame,从而将主窗口界面划分成多个区域。

Frame 控件的常用属性如下表所示:

属性说明
bg设置 Frame 的背景颜色
bd指定 Frame 的边框宽度
colormap指定 Frame 组件及其子组件的颜色映射
container布尔值参数,若参数值为 True,则窗体将被用作容器使用,一些其他程序也可以被嵌入。
cursor指定鼠标在 Frame 上飘过的鼠标样式,默认由系统指定
height/width设置 Frame 的高度和宽度
highlightbackground指定当 Frame 没有获得焦点的时候高亮边框的颜色,通常由系统指定为标准颜色
highlightcolor指定当 Frame 获得焦点的时候高亮边框的颜色
highlightthickness指定高亮边框的宽度,默认值是 0
padx/pady距离主窗口在水平/垂直方向上的外边距
relief指定边框的样式,参数值 “sunken”,“raised”,“groove” 或 “ridge”,“flat”,默认为 "falt’
takefocus布尔值参数,默认为 False,指定该组件是否接受输入焦点(即用户通过 Tab 键将焦点转移上来)

下面看一组简单的示例,通过 Frame 将主窗口分成左右两个部分,如下所示:

  1. import tkinter as tk
  2. win = tk.Tk()
  3. win.title("Python学习")
  4. win.geometry('400x350+200+200')
  5. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. # 在主窗口上添加一个frame控件
  7. frame1 = tk.Frame(win)
  8. frame1.pack()
  9. # 在frame_1上添加另外两个frame, 一个在靠左,一个靠右
  10. #左侧的frame
  11. frame_left = tk.Frame(frame1)
  12. tk.Label(frame_left,text='左侧标签1',bg='green',width=10,height=5).grid(row =0,column=0)
  13. tk.Label(frame_left,text='左侧标签2',bg='blue',width=10,height=5).grid(row = 1 ,column =1)
  14. frame_left.pack(side=tk.LEFT)
  15. frame_right = tk.Frame(frame1)
  16. tk.Label(frame_right,text='右侧标签1',bg='gray',width=10,height=5).grid(row = 0 ,column =1)
  17. tk.Label(frame_right,text='右侧标签2',bg='pink',width=10,height=5).grid(row = 1 ,column =0)
  18. tk.Label(frame_right,text='右侧标签3',bg='purple',width=10,height=5).grid(row= 1,column=1)
  19. frame_right.pack(side=tk.RIGHT)
  20. win.mainloop()

上述示例利用 Frame 控件将主窗口分成了左右两个子区域,同时在各自区域中添加了 Label 标签,而且区域之间互不干扰。采用这种分区、分块的布局方式,可以使得 GUI 程序更加规范、简洁化。

1.3.2.2 LabelFrame控件

LabelFrame 控件也是一种容器类型的控件,它属于是 Frame 控件的变体,因此它们的属性选项大体相同。

在默认情况下,LabelFrame 会在其包裹的子组件周围绘制一个边框和一个标题。当我们想要将一些相关的组件分为一组时,就可以使用 LabelFrame 组件,比如把一系列 Radiobutton(单选按钮)放在一起来供用户选择。

同 Frame 控件一样,LabelFrame 的主要作用也是对控件进行分组处理,下面看一个具体的实例:

  1. import tkinter as tk
  2. win = tk.Tk()
  3. win.title("Python学习")
  4. win.geometry('800x350+200+200')
  5. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. # 定义第一个容器,使用 labelanchor ='w' 来设置标题的方位
  7. frame_left = tk.LabelFrame(win, text="教程", labelanchor="w",bg='#5CACEE')
  8. # 使用 place 控制 LabelFrame 的位置
  9. frame_left.place(relx=0.2, rely=0.2, relwidth=0.2, relheight=0.5)
  10. label_1 = tk.Label(frame_left, text="C语言")
  11. label_1.place(relx=0.2, rely=0.2)
  12. label_2 = tk.Label(frame_left, text="Python")
  13. label_2.place(relx=0.6, rely=0.2)
  14. label_3 = tk.Label(frame_left, text="Java")
  15. label_3.place(relx=0.2, rely=0.6)
  16. label_4 = tk.Label(frame_left, text="C++")
  17. label_4.place(relx=0.6, rely=0.6)
  18. # 定义第二个容器,使用 labelanchor ='w' 来设置标题的方位
  19. frame_right = tk.LabelFrame(win, text="辅导班", labelanchor="w",bg='#66CDAA')
  20. # 使用 place 控制 LabelFrame 的位置
  21. frame_right.place(relx=0.5, rely=0.2, relwidth=0.3, relheight=0.6)
  22. label_1 = tk.Label(frame_right, text="C语言辅导班")
  23. label_1.place(relx=0.2, rely=0.2)
  24. label_2 = tk.Label(frame_right, text="数据结构")
  25. label_2.place(relx=0.6, rely=0.2)
  26. label_3 = tk.Label(frame_right, text="C++辅导班")
  27. label_3.place(relx=0.2, rely=0.6)
  28. label_4 = tk.Label(frame_right, text="Python答疑")
  29. label_4.place(relx=0.6, rely=0.6)
  30. win.mainloop()
1.3.2.2 PanedWindow控件

PanedWindow(窗格界面)也可以理解成一个特殊的 Frame 控件,它是 Tkinter 8.4 版本后新增的空间管理组件,其主要目的是为其他组件提供一个容器或者框架,从而实现以分块的形式对图形界面进行布局。

与 Frame 控件不同, PanedWindow 允许用户自主地调整界面划分以及每块区域的大小。因此,当您需要让用户自己调节每块区域的大小时,就可以采用 PanedWindow 作为组件载体来进行界面的布局。

不仅如此 PanedWindow 组件还提供了“手柄” 功能(设置参数 showhandle=True 来启用),通过拖动“手柄”图标也可以改变每块区域的大小。PanedWindow 组件语法格式如下所示:

PanedWindow(master=None, **options)

其中 master 表示父组件,即包裹该组件的上层组件。其常用属性如下表所示:

属性说明
handlepad调节“手柄”的位置; 比如当 orient =‘vertical’ 设置垂直时,handlepad 表示“分割线”上的手柄与左端的距离,默认为 8 像素
handlesize设置“手柄”的尺寸(由于“手柄”必须是一个正方形,所以是设置正方形的边长)默认为 8 像素
opaqueresize该选项定义了用户调整窗格尺寸的操作,如果该选项的值为 True(默认),窗格的尺寸随用户鼠标的拖拽而改变 ,如果该选项的值为 False,那么窗格的尺寸,在用户释放鼠标时才会更新到新的位置上
orient指定窗格的分布方式,默认为水平方向分布(“horizontal”),或者还可以设置为垂直纵向分布(“vertical”)
relif指定边框的样式,默认为 “flat”,还可以设置为 “sunken”,“raised”,“groove” 或 “ridge”
sashpad设置每一条分割线到窗格间的间距
sashrelief设置分割线的样式,默认值是:“flat”,还可以设置 “sunken”,“raised”,“groove” 或 “ridge”
sashwidth设置分割线的宽度
showhandle设置是否显示调节窗格的手柄,默认为 False
height/width设置 PanedWindow 的高度、宽度,若不设置,则其大小由其子组件的尺寸决定

PanedWindow 的常用方法如下表所示:

方法说明
add(child)添加一个新的子组件到窗格中语法格式 add(child,**option),参数值 after、before、sticky
forget(child)删除一个子组件
panecget(child, option)获得子组件指定选项的值
paneconfig(child, **options)设置子组件的各种选项
panes()将父组件中包含的子组件以列表的形式返回
sash_coord(index)返回一个二元组表示指定分割线的起点坐标
sash_place(index, x, y)将指定的分割线移动到一个新的位置

下面示例设计一个简单的界面布局,然后将图形界面分割成四部分:创建一个水平方向的 PanedWindow,并向其中添加两个 Label 组件,之后创建一个垂直的方向的 PanedWindow,并向其中中添加两个 Label 标签。示例代码如下:

  1. import tkinter as tk
  2. win = tk.Tk()
  3. win.title("Python学习")
  4. win.geometry('400x400+200+200')
  5. win.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  6. # 创建一个水平方向的 panedwindow,并添加到主窗口中,默认为水平方向
  7. p_window1 = tk.PanedWindow(win)
  8. p_window1.pack(fill=tk.BOTH, expand=1)
  9. # 在窗口区的左侧添加两个水平方向的 Label
  10. left1 =tk. Label(p_window1, text='Python', bg='#7CCD7C', width=10,font=('微软雅黑',15))
  11. p_window1.add(left1)
  12. left2 =tk.Label(p_window1, text='C++', bg='#9AC0CD', width=10,font=('微软雅黑',15))
  13. p_window1.add(left2)
  14. # 创建一个垂直方向的panedwindow,并添加一个手柄,设置分割线样式
  15. p_window2 = tk.PanedWindow(orient=tk.VERTICAL,showhandle=True,sashrelief='sunken')
  16. # 添加到 p_window1中
  17. p_window1.add(p_window2)
  18. # 在 p_window2 中添加两个垂直方向的标签
  19. top_label =tk. Label(p_window2, text='教程', bg='#7171C6', height=8,font=('宋体',15))
  20. p_window2.add(top_label)
  21. bottom_label =tk. Label(p_window2, text='辅导班', bg='#8968CD',font=('宋体',15))
  22. p_window2.add(bottom_label)
  23. win.mainloop()

注意:从上述示例中可以看出 PanedWindw 会为每一个 Label 控件创建一个独立的窗格, 当我们将鼠标悬停在两个控件接壤处的白色边框上时,就会出现可以上下或者左右拉伸的指示光标,用户按照可以按照自己的意愿来调整每块区域的大小。

1.3.2.2 Toplevel控件

Topleve 是一个顶级窗口控件(也被称为“子窗体”控件),同样类似于 Frame 控件, 不过该控件会脱离根窗口另行创建一个独立窗口,因此它的存在形式不同于上述其他容器。

Toplevel 控件同样隶属于主窗口的子组件,只是存在形式特殊而已。Toplevel 是主窗口之外的弹出框窗口(通过事件来触发执行),在这个窗口内也可以包含其他组件。但需要注意,顶级窗口并不是必须位于窗口的顶部位置,之所以称其为顶级窗口,是因为相对于主窗口而言,Topleve 位于主窗口的上一层。

Toplevel 控件拥有根窗口控件的所有方法和属性,同时它还拥有一些独有的方法,如下表所示:

方法说明
deiconify()在使用 iconify() 或 withdraw() 方法后,即窗口最小化和移除窗口后(只是看不见,并没销毁),使用该方法来显示该窗口
frame()返回一个系统特定的窗口识别码
group(window)将顶级窗口加入 window 窗口群组中,如果忽略该参数,将返回当前窗口群的主窗口
iconify()将窗口图标化(最小化),需要重新显示窗口,使用 deiconify() 方法
protocol(name, function)将回调函数 function 与相应的规则 name 绑定;1) name 参数可以是 “WM_DELETE_WINDOW”:窗口被关闭的时候;2) name 参数可以是 “WM_SAVE_YOURSELF”:窗口被保存的时候;3) name 参数可以是 “WM_TAKE_FOCUS”:窗口获得焦点的时候。
state()设置和获得当前窗口的状态,参数值 “normal”(正常状态),“withdrawn(移除窗口)”,“icon”(最小化)和 “zoomed”(放大)
transient(master)指定为 master 的临时窗口
withdraw()将窗口从屏幕上移除,只是移动到了窗口之外,并没销毁,需要重新显示窗口,使用 deiconify() 方法

下面看一组关于创建 Toplevel 的示例,如下所示:

  1. import tkinter as tk
  2. root = tk.Tk()
  3. root.config(bg='#87CEEB')
  4. root.title("Python学习")
  5. root.geometry('400x350+300+300')
  6. root.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  7. def create_toplevel():
  8. top = tk.Toplevel()
  9. top.title("Python学习")
  10. top.geometry('300x200+100+100')
  11. top.iconbitmap('C:/Users/Administrator/Desktop/logo.ico')
  12. # 多行文本显示Message控件
  13. msg = tk.Label(top, text="Python学习",bg='#9BCD9B',font=('宋体',15))
  14. msg.pack()
  15. tk.Button(root, text="点击创建Toplevel组件",width=20,height=3,command=create_toplevel).pack()
  16. root.mainloop()
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索