第二部分 Python提高—GUI图形用户界面编程(四)

布局管理器
一个GUI 应用程序必然有大量的组件,这些组件如何排布?这时候,就需要使用tkinter提供的布局管理器帮助我们组织、管理在父组件中子组件的布局方式。tkinter 提供了三种管理器:pack、grid、place

grid 布局管理器

grid 表格布局,采用表格结构组织组件。子组件的位置由行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。

grid()方法提供的选项

选项项说明取值范围
column单元格的列号从0 开始的正整数
columnspan跨列,跨越的列数正整数
row单元格的行号从0 开始的正整数
rowspan跨行,跨越的行数正整数
ipadx, ipady设置子组件之间的间隔,x 方向或者y 方向,默认单位为像素非负浮点数,默认0.0
padx, pady与之并列的组件之间的间隔,x 方向或者y 方向,默认单位是像素非负浮点数,默认0.0
sticky组件紧贴所在单元格的某一角,对应于东南西北中以及4 个角“n”, “s”, “w”, “e”,“nw”, “sw”, “se”,“ne”, “center”(默认)

示例 grid 布局用法-登录界面设计

from tkinter import *
from tkinter import messagebox
import random
class Application(Frame):
	def __init__(self, master=None):
		super().__init__(master) # super()代表的是父类的定义,而不是父类对象
		self.master = master
		self.pack()
		self.createWidget()
	def createWidget(self):
		"""通过grid 布局实现登录界面"""
		self.label01 = Label(self,text="用户名")
		self.label01.grid(row=0,column=0)
		self.entry01 = Entry(self)
		self.entry01.grid(row=0,column=1)
		Label(self,text="用户名为手机号").grid(row=0,column=2)
		Label(self, text="密码").grid(row=1, column=0)
		Entry(self, show="*").grid(row=1, column=1)
		Button(self, text="登录").grid(row=2, column=1, sticky=EW)
		Button(self, text="取消").grid(row=2, column=2, sticky=E)
if __name__ == '__main__':
	root = Tk()
	root.geometry("400x90+200+300")
	app = Application(master=root)
	root.mainloop()

在这里插入图片描述

示例 通过grid 布局-实现计算器软件界面

"""计算器软件界面的设计"""
from tkinter import *
from tkinter import messagebox
import random
class Application(Frame):
	def __init__(self, master=None):
		super().__init__(master)  # super()代表的是父类的定义,而不是父类	对象
		self.master = master
		self.pack()
		self.createWidget()

	def createWidget(self):
		"""通过grid 布局实现计算器的界面"""

		btnText = (("MC", "M+", "M-", "MR"),
			   ("C", "±", "/", " "),
			   (7, 8, 9, "-"),
			   (4, 5, 6, "+"),
			   (1, 2, 3, "="),
			   (0, "."))
		Entry(self).grid(row=0, column=0, columnspan=4, pady=10)
		for rindex, r in enumerate(btnText):
			for cindex, c in enumerate(r):
				if c == "=":
					Button(self, text=c, width=2).grid(row=rindex + 1, column=cindex, rowspan=2, sticky=NSEW)
				elif c == 0:
					Button(self, text=c, width=2).grid(row=rindex + 1, column=cindex, columnspan=2, sticky=NSEW)
				elif c == ".":
					Button(self, text=c, width=2) \
					.grid(row=rindex + 1, column=cindex + 1, sticky=NSEW)
				else:
					Button(self, text=c, width=2) \
					.grid(row=rindex + 1, column=cindex, sticky=NSEW)
if __name__ == '__main__':
	root = Tk()
	root.geometry("200x200+200+300")
	app = Application(master=root)
	root.mainloop()

这里是引用

pack 布局管理器

pack 按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布。如果不指定任何选项,默认在父组件中自顶向下垂直添加组件。pack 是代码量最少,最简单的一种,可以用于快速生成界面。

pack()方法提供的选项

名称描述取值范围
expand当值为“yes”时,side 选项无效。组件显示在父配件中心位置;若fill 选项为”both”,则填充父组件的剩余空间“yes”, 自然数,”no”, 0(默认值”no”或0)
fill填充x(y)方向上的空间,当属性side=”top”或”bottom”时,填充x 方向;当属性side=”left”或”right”时,填充”y”方向;当expand 选项为”yes”时,填充父组件的剩余空间“x”, “y”, “both”,“none”(默认值为none)
ipadx,ipady设置子组件之间的间隔,x 方向或者y 方向,默认单位为像素非负浮点数,默认0.0
padx,pady与之并列的组件之间的间隔,x 方向或者y 方向,默认单位是像素非负浮点数,默认0.0
side定义停靠在父组件的哪一边上“ top ” , “ bottom ” ,“left”, “right”(默认为”top”)
before将本组件于所选组建对象之前pack,类似于先创建本组件再创建选定组件已经pack 后的组件对象
after将本组件于所选组建对象之后pack,类似于先创建选定组件再本组件已经pack 后的组件对象
in_将本组件作为所选组建对象的子组件,类似于指定本组件的master 为选定组件已经pack 后的组件对象
anchor对齐方式,左对齐”w”,右对齐”e”,顶对齐”n”,底对齐”s”“n”, “s”, “w”, “e”,“nw”, “sw”, “se”,“ne”, “center”(默认)

建议 :如上列出了pack 布局所有的属性,但是不需要挨个熟悉,了解基本的即可。pack 适用于简单的垂直或水平排布,如果需要复杂的布局可以使用grid 或place。

示例 pack 布局用法,制作钢琴按键布局

#coding=utf-8
#测试pack 布局管理
from tkinter import *
root = Tk();root.geometry("700x220")
#Frame 是一个矩形区域,就是用来防止其他子组件
f1 = Frame(root)
f1.pack()
f2 = Frame(root);f2.pack()
btnText = ("流行风","中国风","日本风","重金属","轻音乐")
for txt in btnText:
	Button(f1,text=txt).pack(side="left",padx="10")
for i in range(1,20):
	Button(f2,width=5,height=10,bg="black" if i%2==0 else
"white").pack(side="left")
root.mainloop()

在这里插入图片描述

place 布局管理器

place 布局管理器可以通过坐标精确控制组件的位置,适用于一些布局更加灵活的场景。

place()方法的选项

选项说明取值范围
x,y组件左上角的绝对坐标(相对于窗口)非负整数x 和y 选项用于设置偏移( 像素) , 如果同时设置relx(rely) 和x(y),那么place 将优先计算relx 和rely,然后再实现x 和y 指定的偏移值
relx,rely组件左上角的坐标(相对于父容器)relx 是相对父组件的位置。0 是最左边,0.5 是正中间,1是最右边;rely 是相对父组件的位置。0 是最上边,0.5 是正中间,1是最下边;
width,height组件的宽度和高度非负整数
relwidth,relheight组件的宽度和高度(相对于父容器)与relx、rely 取值类似,但是相对于父组件的尺寸
anchor对齐方式,左对齐”w”,右对齐”e”,顶对齐”n”,底对齐”s”“n”, “s”, “w”, “e”, “nw”, “sw”, “se”,“ne”, “center”(默认)

示例 place 布局管理-基本用法测试

#coding=utf-8
from tkinter import *
root = Tk();root.geometry("500x300")
root.title("布局管理place");root["bg"]="white"
f1 = Frame(root,width=200,height=200,bg="green")
f1.place(x=30,y=30)
Button(root,text="ccc").place(relx=0.5,rely=0,
x=100,y=200,relwidth=0.2,relheight=0.2)
Button(f1,text="天空程序员").place(relx=0.6,rely=0.7)
Button(f1,text="beijingnihao").place(relx=0.2,rely=0.2)
root.mainloop()

这里是引用

示例 place 布局管理-扑克牌游戏demo

from tkinter import *
class Application(Frame):
	def __init__(self, master=None):
		super().__init__(master) # super()代表的是父类的定义,而不是父类对象
		self.master = master
		self.pack()
		self.createWidget()
	def createWidget(self):
		"""通过place 布局管理器实现扑克牌位置控制"""
		# self.photo = PhotoImage(file="imgs/puke/puke1.gif")
		# self.puke1 = Label(self.master,image=self.photo)
		# self.puke1.place(x=10,y=50)
		self.photos = [PhotoImage(file=r"F:\python_l\pythonProject1\puke\puke"+str(i+1)+".gif") for i in range(10)]
		self.pukes = [Label(self.master,image=self.photos[i]) for i in range(10)]
		for i in range(10):
			self.pukes[i].place(x=10+i*40,y=50)
			# 为所有的Label 增加事件处理
			self.pukes[0].bind_class("Label","<Button-1>",self.chupai)
	def chupai(self,event):
		print(event.widget.winfo_geometry())
		print(event.widget.winfo_y())
		if event.widget.winfo_y() == 50:
			event.widget.place(y=30)
		else:
			event.widget.place(y=50)
if __name__ == '__main__':
	root = Tk()
	root.geometry("600x270+200+300")
	app = Application(master=root)
	root.mainloop()

这里是引用

  • 34
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_44006060

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值