python --Tkinter详解
Posted 像风一样的男人@
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python --Tkinter详解相关的知识,希望对你有一定的参考价值。
简介
-
tkinter
tkinter(Tk interface)是Python的标准GUl库,支持跨平台的GUl程序开发。tkinter适合小型的GUl程序编写,也特别适合初学者学习GUl编程。 -
wxPython
wxPython是比较流行的GUI库,适合大型应用程序开发,功能强于tkinter,整体设计框架类似于MFC(MicrosoftFoundation Classes微软基础类库). -
PyQT
Qt是一种开源的GUI库,适合大型GUI程序开发,PyQt是Qt工具包标准的Python实现。我们也可以使用QtDesginer界面设计器快速开发GUl应用程序.
官网
https://docs.python.org/3/library/tkinter.html
创建一个窗口
from tkinter import *
root = Tk() # 实例化TK
root.mainloop() # 进入事件循环
第一个GUI带事件的程序
from tkinter import *
from tkinter import messagebox
root = Tk()
bt = Button(root)
bt['text'] = '点我'
bt.pack()
def dianji(e):
messagebox.showinfo('message', 'give flower') # 提示框
bt.bind('<Button-1>', dianji) # 绑定点击事件
root.mainloop() # 进入事件循环
窗口大小和位置
geometry()尺寸
from tkinter import *
from tkinter import messagebox
root = Tk()
root.title('我的gui程序')
root.geometry('500x300+100+200')
# 500宽度 300高度 距屏幕左侧100像素 顶部200像素
bt = Button(root)
bt['text'] = '点我'
bt.pack()
def dianji(e):
print(e)
messagebox.showinfo('message', 'give flower') # 提示框
bt.bind('<Button-1>', dianji) # 绑定点击事件
root.mainloop() # 进入事件循环
窗口放至屏幕中间
from tkinter import *
app = Tk()
app.title('拜液用户管理')
sw = app.winfo_screenwidth()
# 得到屏幕宽度
sh = app.winfo_screenheight()
# 得到屏幕高度
ww = 610
wh = 400
x = (sw - ww) / 2
y = (sh - wh) / 2
app.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
app.resizable(width=False, height=False)
app.mainloop()
常用组件汇总
组件类关系图
GUI面向对象写法
通过类 Application 组织整个 GUI 程序,类 Application继承了 Frame 及通过继承拥有了父类的特性。通过构造函数__init__()初始化窗口中的对象,通过 createWidgets()方法创建窗口中的对象。
Frame 框架是一个 tkinter 组件,表示一个矩形的区域。
Frame 一般作为容器使用,可以放置其他组件,从而实现复杂的布局。
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
# 创建组件
self.btn01 = Button(self)
self.btn01['text'] = '点击送花'
self.btn01.pack()
self.btn01['command'] = self.songhua
# 创建一个退出按钮
self.btnQuit = Button(self, text='退出', command=root.destroy)
self.btnQuit.pack()
def songhua(self):
messagebox.showinfo('送花', '送你99朵玫瑰花')
root = Tk()
root.geometry('400x100+200+300')
root.title('一个经典的GUI程序类的测试')
app = Application(master=root)
root.mainloop()
简单组件
Label 标签
Label(标签)主要用于显示文本信息,也可以显示图像。
Label(标签)有这样一些常见属性:
-
width,height
用于指定区域大小,如果显示是文本,则以单个英文字符大小为单位(一个汉字宽度占 2 个字符位置,高度和英文字符一样);如果显示是图像,则以像素为单位。默认值是根据具体显示的内容动态调整。 -
font
指定字体和字体大小,如:font =(font_name,size) -
image
显示在 Label 上的图像,目前 tkinter 只支持 gif 格式。 -
fg 和 bg
fg(foreground):前景色、bg(background):背景色 -
justify
针对多行文字的对齐,可设置 justify 属性,可选值"left" “center” “right”
【示例】Label(标签)的用法
from tkinter import *
class Application(Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
# 创建组件
self.label01 = Label(self, text='关关雎鸠', width=10, height=2,
bg='black', fg='white')
self.label01.pack()
self.label02 = Label(self, text='hebut', width=10, height=2,
bg='blue', fg='white', font=('黑体', 30))
self.label02.pack()
# 显示图像
global photo
# photo = PhotoImage(file='pic01.gif')
# self.label03 = Label(self, image=photo)
# self.label03.pack()
# 显示多行文本
self.label04 = Label(self, text='hebut\\n关关雎鸠', borderwidth=1, relief='groove', justify='right')
self.label04.pack()
if __name__ == '__main__':
root = Tk()
root.geometry('400x500+200+300')
app = Application(master=root)
root.mainloop()
Options 选项详解
通过学习 Label 组件,我们发现可以通过 Options 设置组件的属性,从而控制组件的各种状态。比如:宽度、高度、颜色、位置等等。
我们可以通过三种方式设置 Options 选项,这在各种 GUI 组件中用法都一致。
1.创建对象时,使用可变参数
fred = Button(self, fg="red", bg="blue")
2.创建对象后,使用字典索引方式
fred["fg"] = "red"
fred["bg"] = "blue"
3 创建对象后,使用 config()方法
fred.config(fg="red", bg="blue")
如何查看组件的 Options 选项:
1.可以通过打印 config()方法的返回值,查看 Options 选项 print(fred.config())
2.通过在 IDE 中,点击组件对象的构造方法,进入到方法内观察:
上面代码中有:“standard options 标准选项”和“widget-specific options 组件特定选项”。我们将常见的选项汇总如下:
Button
Button(按钮)用来执行用户的单击操作。Button 可以包含文本,也可以包含图像。按钮被单击后会自动调用对应事件绑定的方法。
【示例】Button 按钮用法(文字、图片、事件)
#测试Button组件的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
# 创建组件
self.btn01 = Button(root, text="登录", width=6, height=3, anchor=CENTER, command=self.login)
self.btn01.pack()
global photo
# photo = PhotoImage(file="pic01.gif")
# self.btn02 = Button(root,image=photo,command=self.login)
# self.btn02.pack()
# self.btn02.config(state="disabled") #设置按钮为禁用
def login(self):
messagebox.showinfo("学习系统", "登录成功!欢迎开始学习!")
if __name__ == '__main__':
root = Tk()
root.geometry("400x400+200+300")
app = Application(master=root)
root.mainloop()
Entry 单行文本框
Entry 用来接收一行字符串的控件。如果用户输入的文字长度长于 Entry 控件的宽度时, 文字会自动向后滚动。如果想输入多行文本, 需要使用 Text 控件。
【示例】Entry 单行文本框实现简单登录界面
# 测试 Entry 组件的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
# 创建登录界面的组件
self.label01 = Label(self, text="用户名")
self.label01.pack()
# StringVar 变量绑定到指定的组件。
# StringVar 变量的值发生变化,组件内容也变化;
# 组件内容发生变化,StringVar 变量的值也发生变化。 v1 = StringVar()
v1 = StringVar()
self.entry01 = Entry(self, textvariable=v1)
self.entry01.pack()
v1.set("admin")
print(v1.get())
print(self.entry01.get())
# 创建密码框
self.label02 = Label(self, text="密码")
self.label02.pack()
v2 = StringVar()
self.entry02 = Entry(self, textvariable=v2, show="*")
self.entry02.pack()
Button(self, text="登陆", command=self.login).pack()
def login(self):
username = self.entry01.get()
pwd = self.entry02.get()
print("去数据库比对用户名和密码!")
print("用户名:" + username)
print("密码:" + pwd)
if username == "关关雎鸠" and pwd == "123456":
messagebox.showinfo("学习系统", "登录成功!欢迎开始学习!")
else:
messagebox.showinfo("学习系统", "登录失败!用户名或密码错误!")
if __name__ == '__main__':
root = Tk()
root.geometry("400x130+200+300")
app = Application(master=root)
root.mainloop()
Text 多行文本框
Text(多行文本框)的主要用于显示多行文本,还可以显示网页链接, 图片, HTML 页面, 甚至 CSS 样式表,添加组件等。因此,也常被当做简单的文本处理器、文本编辑器或者网页浏览器来使用。比如 IDLE 就是 Text 组件构成的。
【示例】Text 多行文本框基本用法(文本输入、组件和图像显示)
# 测试 Text 多行文本框组件的基本用法,使用面向对象的方式
from tkinter import *
import webbrowser
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
self.w1 = Text(root, width=40, height=12, bg="gray")
# 宽度 20 个字母(10 个汉字),高度一个行高
self.w1.pack()
self.w1.insert(1.0, "0123456789\\nabcdefg")
self.w1.insert(2.3, "锄禾日当午,汗滴禾下土。谁知盘中餐,粒粒皆辛苦\\n")
Button(self, text="重复插入文本", command=self.insertText).pack(side="left")
Button(self, text="返回文本", command=self.returnText).pack(side="left")
Button(self, text="添加图片", command=self.addImage).pack(side="left")
Button(self, text="添加组件", command=self.addWidget).pack(side="left")
Button(self, text="通过 tag 精确控制文本", command=self.testTag).pack(side="left")
def insertText(self):
# INSERT 索引表示在光标处插入
self.w1.insert(INSERT, '关关雎鸠')
# END 索引号表示在最后插入
self.w1.insert(END, '[hebut]')
self.w1.insert(1.8, "关关雎鸠")
def returnText(self):
# Indexes(索引)是用来指向 Text 组件中文本的位置,Text 的组件索引也是对应实际字符之间的位置。
# 核心:行号以 1 开始 列号以 0 开始
print(self.w1.get(1.2, 1.6))
print("所有文本内容:\\n" + self.w1.get(1.0, END))
def addImage(self):
# global photo
self.photo = PhotoImage(file="pic01.gif")
self.w1.image_create(END, image=self.photo)
def addWidget(self):
b1 = Button(self.w1, text='爱学习')
# 在text 创建组件的命令
self.w1.window_create(INSERT, window=b1)
def testTag(self):
self.w1.delete(1.0, END)
self.w1.insert(INSERT, "good good study,day day up!\\nhebut\\n关关雎鸠\\n百度一下")
self.w1.tag_add("good", 1.0, 1.9)
self.w1.tag_config("good", background="yellow", foreground="red")
self.w1.tag_add("baidu", 4.0, 4.4)
self.w1.tag_config("baidu", underline=True)
self.w1.tag_bind("baidu", "<Button-1>", self.webshow)
def webshow(self, event):
webbrowser.open("http://www.baidu.com")
if __name__ == '__main__':
root = Tk()
root.geometry("450x300+200+300")
app = Application(master=root)
root.mainloop()
利用 Tags 实现更加强大的文本显示和控制
Tags 通常用于改变 Text 组件中内容的样式和功能。你可以修改文本的字体、尺寸和颜色。另外,Tags 还允许你将文本、嵌入的组件和图片与鼠标和键盘等事件相关联。
【示例】利用 Tag 属性实现更复杂文本控制
from tkinter import *
import webbrowser
root= Tk();root.geometry("300x300+400+400")
w1= Text(root,width=40,height=20) #宽度 20 个字母(10 个汉字),高度一个行高
w1.pack()
w1.insert(INSERT,"good goodstudy,day day up!\\nhebut\\n关关雎鸠\\n百度一下")
w1.tag_add("good",1.0,1.9)
w1.tag_config("good",background="yellow",foreground="red")
w1.tag_add("baidu",4.0,4.4)
w1.tag_config("baidu",underline=True)
def webshow(event):
webbrowser.open("http://www.baidu.com")
w1.tag_bind("baidu","<Button-1>",webshow)
root.mainloop()
Radiobutton 单选按钮
Radiobutton 控件用于选择同一组单选按钮中的一个。Radiobutton 可以显示文本,也可以显示图像。
【示例】Radiobutton 基础用法
测试 Radiobutton 组件的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
self.v = StringVar();
self.v.set("F")
self.r1 = Radiobutton(self, text="男性", value="M", variable=self.v)
self.r2 = Radiobutton(self, text="女性", value="F", variable=self.v)
self.r1.pack(side="left");self.r2.pack(side="left")
Button(self, text="确定",command=self.confirm).pack(side="left")
def confirm(self):
messagebox.showinfo("测试","选择的性别:"+self.v.get())
if __name__ == '__main__':
root = Tk()
root.geometry("400x50+200+300")
app = Application(master=root)
root.mainloop()
Checkbutton 复选按钮
Checkbutton 控件用于选择多个按钮的情况。Checkbutton可以显示文本,也可以显示图像。
【示例】Checkbutton 复选按钮用法
#测试 Checkbutton 组件的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
self.codeHobby = IntVar();
self.videoHobby = IntVar()
print(self.codeHobby.get()) # 默认值是 0
self.c1 = Checkbutton(self, text="敲代码",variable=self.codeHobby,onvalue=1, offvalue=0)
self.c2 = Checkbutton(self, text="看视频", variable=self.videoHobby,onvalue=1, offvalue=0)
self.c1.pack(side="left")
self.c2.pack(side="left")
Button(self, text="确定",command=self.confirm).pack(side="left")
def confirm(self):
if self.videoHobby.get() == 1:
messagebox.showinfo("测试","看视频,都是正常人有的爱好!你喜欢看什么类型?")
if self.codeHobby.get() == 1:
messagebox.showinfo("测试","抓获野生程序猿一只!")
if __name__ == '__main__':
root = Tk()
root.geometry("400x50+200+300")
app = Application(master=root)
root.mainloop()
canvas 画布
canvas(画布)是一个矩形区域,可以放置图形、图像、组件等。
【示例】canvas 画布使用基础示例
# 测试 Canvas 组件的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
import random
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
self.master = master
self.pack()
self.createWidget()
def createWidget(self):
self.canvas = Canvas(self, width=300, height=370, bg="green")
self.canvas.pack()
#画一条直线
line = self.canvas.create_line(10, 10, 30, 20, 40, 50)
#画一个矩形.
rect = self.canvas.create_rectangle(50, 50, 100, 100)
#画一个椭圆.坐标两双。为椭圆的边界矩形左上角和底部右下角
oval = self.canvas.create_oval(50, 50, 100, 100)
global photo
photo = PhotoImage(file="pic01.gif")
self.canvas.create_image(150,300,image=photo)
Button(self, text="画 10 个矩形", command=self.draw50Recg).pack(side="left")
def draw50Recg(self):
for i in range(0, 10):
x1 =random.randrange(int(self.canvas["width"])/2)
y1 =random.randrange(int(self.canvas["height"])/2)
x2 = x1 +random.randrange(int(self.canvas["width"])/2)
y2 = y1 +random.randrange(int(self.canvas["height"])/2)
self.canvas.create_rectangle(x1, y1, x2, y2)
if __name__ == '__main__':
root = Tk()
root.geometry("400x400+200+300")
app = Application(master=root)
root.mainloop()
布局管理器
一个 GUI 应用程序必然有大量的组件,这些组件如何排布?这时候,就需要使用 tkinter 提供的布局管理器帮助我们组织、管理在父组件中子组件的布局方式。tkinter 提供了三种管理器:pack、grid、place。
grid 布局管理器
grid 表格布局,采用表格结构组织组件。子组件的位置由行和列的单元格来确定,并且可以跨行和跨列,从而实现复杂的布局。
grid()方法提供的选项
【示例】grid 布局用法-登录界面设计
# 测试 Grid 布局管理器的基本用法,使用面向对象的方式
from tkinter import *
from tkinter import messagebox
import random
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
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=EW)
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()代表的是父类的定义,而不是父类对象
super().__init__(master)
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("200x250+200+300")
app = Application(master=root)
root.mainloop()
pack 布局管理器
pack 按照组件的创建顺序将子组件添加到父组件中,按照垂直或者水平的方向自然排布。如果不指定任何选项,默认在父组件中自顶向下垂直添加组件。
pack 是代码量最少,最简单的一种,可以用于快速生成界面。
pack()方法提供的选项
【示例】pack 布局用法,制作钢琴按键布局
# 测试 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()方法的选项
【示例】place 布局管理-基本用法测试
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="hebut").place(relx=0.5,rely=0,x=100,y=200,relwidth=0.2,relheight=0.2)
Button(f1,text="programmer").place(relx=0.6,rely=0.7)
Button(f1,text="关关雎鸠").place(relx=0.2,rely=0.2)
root.mainloop()
【示例】place 布局管理-扑克牌游戏 demo
扑克牌游戏的界面设计
from tkinter import *
class Application(Frame):
def __init__(self, master=None): # super()代表的是父类的定义,而不是父类对象
super().__init__(master)
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="imgs/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("600x370+200+300")
app = Application(master=root)
root.mainloop()
事件处理
一个 GUI 应用整个生命周期都处在一个消息循环 (event loop) 中。它等待事件的发生,并作出相应的处理。
Tkinter 提供了用以处理相关事件的机制. 处理函数可被绑定给各个控件的各种事件。
widget.bind(event, handler)
如果相关事件发生, handler 函数会被触发, 事件对象 event 会传递给 handler 函数
鼠标和键盘事件
event 对象常用属性
【示例】鼠标事件和键盘事件用法测试
#测试键盘和鼠标事件
from tkinter import *
root = Tk()
root.geometry("530x300")
c1 = Canvas(root,width=200,height=200,bg="green")
c1.pack()
def mouseTest(event):
print("鼠标左键单击位置(相对于父容器):0,1".format(event.x,event.y))
print("鼠标左键单击位置(相对于屏幕):0,1".format(event.x_root,event.y_root))
print("事件绑定的组件:0".format(event.widget))
def testDrag(event):
c1.create_oval(event.x,event.y,event.x+1,event.y+1)
def keyboardTest(event):
print("键的 keycode:0,键的 char:1,键的 keysym:2".format(event.keycode,event.char,event.keysym))
def press_a_test(event):
print("press a")
def release_a_test(event):
print("release a")
c1.bind("<Button-1>",mouseTest)
c1.bind("<B1-Motion>",testDrag)
root.bind("<KeyPress>",keyboardTest)
root.bind("<KeyPress-a>",press_a_test) #只针对小写的a,大写的 A 不管用
root.bind("<KeyRelease-a>",release_a_test)
root.mainloop()
多种事件绑定方式汇总
组件对象的绑定
1.通过 command 属性绑定(适合简单不需获取 event 对象)
Button(root,text=”登录”,command=login)
2.通过 bind()方法绑定(适合需要获取 event 对象)
c1 = Canvas(); c1.bind(“”,drawLine)
组件类的绑定
调用对象的 bind_class 函数,将该组件类所有的组件绑定事件:
w.bind_class(“Widget”,”event”,eventhanler)
比如:btn01.bind_class(“Button”,””,func)
【示例】多种事件绑定方式总结
#多种事件绑定方式汇总
from tkinter import *
root = Tk()
root.geometry("270x30")
def mouseTest1(event):
print("bind()方式绑定,可以获取 event 对象")
print(event.widget)
def mouseTest2(a, b):
print("a=0,b=1".format(a, b))
print("command 方式绑定,不能直接获取 event 对象")
def mouseTest3(event):
print("右键单击事件,绑定给所有按钮啦!!")
print(event.widget)
b1 = Button(root, text="测试 bind()绑定")
b1.pack(side="left")
#bind 方式绑定事件
b1.bind("<Button-1>", mouseTest1)
#command 属性直接绑定事件
b2 = Button(root, text="测试 command2",command=lambda: mouseTest2("关关雎鸠", "hebut"))
b2.pack(side="left")
# 给所有 Button 按钮都绑定右键单击事件<Button-2>
b1.bind_class("Button", "<Button-2>", mouseTest3)
其他组件
OptionMenu 选择项
OptionMenu(选择项)用来做多选一,选中的项会在顶部显示。
【示例】OptionMenu(选择项)的基本用法
#optionmenu 的使用测试
from tkinter import *
root= Tk()
root.geometry("200x100")
v= StringVar(root);
v.set("关关雎鸠")
om= OptionMenu(root,v,"关关雎鸠","在河之洲","窈窕淑女","君子好逑")
om["width"]=10
om.pack(pady=20)
def test1():
print("最喜爱的诗句:",v.get())
#v.set("关关雎鸠") #直接修改了optionmenu中选中的值
Button(root,text="确定",command=test1).pack()
root.mainloop()
Scale 移动滑块
Scale(移动滑块)用于在指定的数值区间,通过滑块的移动来选择值。
【示例】使用 Scale(移动滑块)控制字体大小变化
#optionmenu 的使用测试
from tkinter import *
root= Tk()
root.geometry("400x150")
def test1(value):
print("滑块的值:",value)
newFont= ("宋体",value)
a.config(font=newFont)
s1=Scale(root,from_=10,to=50,length=200,orient=HORIZONTAL,command=test1)
s1.pack()
a= Label(root,text="关关雎鸠",width=10,height=1,bg="black",fg="white")
a.pack()
root.mainloop()
颜色选择框
颜色选择框可以帮助我们设置背景色、前景色、画笔颜色、字体颜色等等。
【示例】颜色选择框基本用法
#askcolor 颜色选择框的测试,改变背景色
from tkinter import *
from tkinter.colorchooser import *
root= Tk();root.geometry("400x150")
def test1():
s1= askcolor(color="red", title="选择背景色")
#((0.0,0.0,255.99609375),'#0000ff')
root.config(bg=s1[1])
Button(root,text="选择背景色",command=test1).pack()
root.mainloop()
文件对话框
文件对话框帮助我们实现可视化的操作目录、操作文件。最后,将文件、目录的信息传入到程序中。文件对话框包含如下一些常用函数
【示例】文件对话框基本用法
from tkinter import *
from tkinter.filedialog import *
root= Tk();root.geometry("400x100")
def test1():
f= askopenfilename(title="上传文件",initialdir="f:/code",filetypes=[("文本文件",".txt")])
#print(f)
show["text"]=f
Button(root,text="选择编辑的文本文件",command=test1).pack()
show= Label(root,width=40,height=3,bg="green")
show.pack()
root.mainloop()
【示例】打开指定 txt 文件,并读出文件内容到窗口
from tkinter import *
from tkinter.filedialog import *
root= Tk();root.geometry("400x100")
def test1():
with askopenfile(title="上传文件",initialdir="f:",filetypes=[("文本文件",".txt")]) as f:
show["text"]=f.read()
Button(root,text="选择编辑的文本文件",command=test1).pack()
show= Label(root,width=40,height=3,bg="green")
show.pack()
root.mainloop()
简单输入对话框
simpledialog(简单对话框)包含如下常用函数:
参数中,title 表示窗口标题;prompt 是提示信息;命名参数**kw 为各种选项:initialvalue(初始值)、minvalue(最小值)、maxvalue(最大值)。
【示例】简单对话框基本用法
#简单对话框
from tkinter.simpledialog import *
root= Tk();root.geometry("400x100")
show= Label(root,width=40,height=3,bg="green")
show.pack()
a=askinteger(title="输入年龄",prompt="请输入年龄 ",initialvalue=18,minvalue=1,maxvalue=150)
show["text"]="年龄:"+str(a)
#askfloat,askstring 自行测试
root.mainloop()
通用消息框
messagebox(通用消息框)用于和用户简单的交互,用户点击确定、取消。如下列出了 messagebox 的常见函数:
【示例】通用消息框的基本用法
#简单对话框
from tkinter import *
from tkinter.messagebox import *
root= Tk();root.geometry("400x100")
a1= showinfo(title="关关雎鸠",message="好好学习,天天向上")
print(a1)
root.mainloop()
ttk 子模块控件
我们再前面学的组件是 tkinter 模块下的组件,整体风格较老较丑。为了弥补这点不足,推出了 ttk 组件。ttk 组件更加美观、功能更加强大。使用 Combobox 替代了原来的Listbox 、新增了 LabeledScale( 带标签的 Scale) 、Notebook(多文档窗口)、Progressbar(进度条)、Treeview(数)等组件。
使用 ttk 组件与使用普通的 Tkinter 组件并没有多大的区别,只要导入 ttk 模块即可。
ttk 子模块的官方文档:
https://docs.python.org/3.7/library/tkinter.ttk.html
菜单和工具栏
GUI 程序通常都有菜单,方便用户的交互。我们一般将菜单分为两种:
1.主菜单
主菜单通常位于 GUI 程序上方。例如:
2.快捷菜单(上下文菜单)
通过鼠标右键单击某个组件对象而弹出的菜单,一般是与该组件相关的操作。
主菜单
主菜单一般包含:文件、编辑、帮助等,位于 GUI 窗口的上面。创建主菜单一般有如下 4 步:
1.创建主菜单栏对象
menubar = tk.Menu(root)
2.创建菜单,并添加到主菜单栏对象
file_menu = tk.Menu(menubar)
menubar.add_cascade(label=”文件”,menu=file_menu)
3.添加菜单项到 2 步中的菜单
file_menu.add_command(label=”打开”)
file_menu.add_command(label=”保存”,accelerator=”^p” command=mySaveFile)
file_menu.add_separator()
file_menu.add_command(label=”退出”)
4.将主菜单栏添加到根窗口
root[“menu”]=menubar
【示例】记事本软件主菜单设计
#记事本软件,练习主菜单的设计
from tkinter import *
from tkinter.messagebox import *
from tkinter.filedialog import *
root= Tk();root.geometry("400x400")
#创建主菜单栏
menubar= Menu(root)
#创建子菜单
menuFile= Menu(menubar)
menuEdit= Menu(menubar)
menuHelp= Menu(menubar)
#将子菜单加入到主菜单栏
menubar.add_cascade(label="文件(F)",menu=menuFile)
menubar.add_cascade(label="编辑(E)",menu=menuEdit)
menubar.add_cascade(label="帮助(H)",menu=menuHelp)
filename= ""
def openFile():
global filename
with askopenfile(title="打开文件") as f:
content =f.read()
w1.insert(INSERT,content)
filename =f.name
print(f.name)
def saveFile():
with open(filename,"w") as f:
content =w1.get(1.0,END)
f.write(content)
def exit():
root.quit()
#添加菜单项
menuFile.add_command(label="打开",accelerator="^O",command=openFile)
menuFile.add_command(label="保存",command=saveFile)
menuFile.add_separator() #添加分割线
menuFile.add_command(label="退出",command=exit)
#将主菜单栏加到根窗口
root["menu"] =menubar
w1= Text(root,width=50,height=30)
w1.pack()
root.mainloop()
上下文菜单
快捷菜单(上下文菜单)是通过鼠标右键单击组件而弹出的菜单,一般是和这个组件相关的操作,比如:剪切、复制、粘贴、属性等。创建快捷菜单步骤如下:
1.创建菜单
menubar = tk.Menu(root)
menubar.add_command(label=”字体”)
2.绑定鼠标右键单击事件
def test(event):
menubar.post(event.x_root,event.y_root) # 在鼠标右键单击坐标处显示菜单
root.bind(“<Button-3>”,test)
【示例】为记事本程序增加快捷菜单
from tkinter import *
from tkinter.colorchooser import *
from tkinter.filedialog import *
root= Tk();root.geometry("400x400")
def openAskColor():
s1= askcolor(color="red", title="选择背景色")
#((0.0,0.0,255.99609375),'#0000ff')
root.config(bg=s1[1])
#创建快捷菜单
menubar2= Menu(root)
menubar2.add_command(label="颜色",command=openAskColor)
menuedit= Menu(menubar2,tearoff=0)
menuedit.add_command(label="剪切")
menuedit.add_command(label="复制")
menuedit.add_command(label="粘贴")
menubar2.add_cascade(label="编辑",menu=menuedit)
def test(event):
#菜单在鼠标右键单击的坐标处显示
menubar2.post(event.x_root,event.y_root)
#编辑区
w1= Text(root,width=50,height=30)
w1.pack()
w1.bind("<Button-3>",test)
root.mainloop()
Tkinter布局(3种)
Tkinter 提供了布局功能,主要包含 pack、grid 和 place 三种布局方法。其中 pack 布局方法在前面使用过,这是最简单的布局方式。
import sys
if sys.version_info.major == 3:
import tkinter as tk
elif sys.version_info.major == 2:
import Tkinter as tk
root = tk.Tk()
root.title(u"pack布局演示")
tk.Button(root, text="side:top").pack(side='top')
tk.Button(root, text="side:bottom").pack(side='bottom')
tk.Button(root, text="side:left").pack(side='left')
tk.Button(root, text="side:right").pack(side='right')
root.mainloop()
grid 布局法就是将屏幕切成表格的样子,通过横向坐标 row 和纵向坐标 column 来指定元素的位置。第一行标记为 0,第一列也标记为 0。
import sys
if sys.version_info.major == 3:
import tkinter as tk
elif sys.version_info.major == 2:
import Tkinter as tk
root = tk.Tk()
root.title(u"grid布局演示")
for row in range(3):
for col in range(4):
text_ = "row=%d, col=%d" % (row, col)
tk.Button(root, text=text_).grid(row=row, column=col)
root.mainloop()
最后一种布局方法是 place,它直接指定元素在父元素中的坐标值,单位是像素。
python初识
变量
一、定义方式
- 下划线(推荐使用) age_of_oldboy = 56
- 变量名只能是 字母、数字或下划线的任意组合
- 变量名的第一个字符不能是数字
- 关键字不能声明为变量名[\'and\', \'as\', \'assert\', \'break\', \'class\', \'continue\', \'def\', \'del\', \'elif\', \'else\', \'except\', \'exec\', \'finally\', \'for\', \'from\', \'global\', \'if\', \'import\', \'in\', \'is\', \'lambda\', \'not\', \'or\', \'pass\', \'print\', \'raise\', \'return\', \'try\', \'while\', \'with\', \'yield\']
二、id、type、value、is、in、hash
- 身份:即内存地址,可以用id()来获取
- 类型:决定了该对象保存的类型,需要遵循什么规则,可用type()来获取该数据类型
- 值:对象的保存的的真实数据
- 等号比较的是value
- is比较的是id
- id相同,意味着type和value必定相同
- value相同type肯定相同,但id可能不同
- 可变:值变,id不变。可变==不可hash
- 不可变:值变,id就变。不可变==可hash
- is运算符用于比较两个对象的身份
- in主要用来判断某一元素是否在某种元素集合中
- 可hash的就是不可变数据类型,不可hash的就是可变数据类型
三、类型分类
- 可变类型:在id不变的情况下,value可以变,则称为可变类型,如列表,字典
- 不可变类型:value一旦改变,id也改变,则称为不可变类型(id变,意味着创建了新的内存空间)
四、变量的声明和引用
name=\'egon\' #变量的声明 name #通过变量名,引用变量的值 print(name) #引用并且打印变量名name对应的值,即\'egon\'
name1=\'lhf\' name2=\'egon\'
name1=\'lhf\' name2=name1
注:变量名没有储藏值的作用,只起到绑定值的作用,改变一个变量的值,变量名重新指向一个值,原值物理地址不变。
常量
- 常量即指不变的量,如圆周率 3.1415926..., 在Python中没有一个专门的语法代表常量,程序员约定俗成用变量名全部大写代表常量AREAS = 56
解释器
1. 解释器:即时调试代码,代码无法永久保存
2. 文件:永久保存代码
在D:\\python_test\\目录下新建文件hello.py,编写代码如下
print(\'hello world\')
执行hello.py,即python D:\\python_test\\hello.py
python内部执行过程如下:
上一步中执行python D:\\python_test\\hello.py时,明确的指出 hello.py 脚本由 python 解释器来执行。
在linux平台中如果想要类似于执行shell脚本一样执行python脚本,例: ./hello.py
,那么就需要在 hello.py 文件的头部指定解释器,如下:
#!/usr/bin/env python #该行只对linux有效 print(\'hello world\')
ps:执行前需给予 hello.py 执行权限,chmod 755 hello.py
程序交互
python3中统一都是input,python2中有raw_input等同于python3的input,另外python2中也有input
1.res=input("python3: ").strip()
2.res=raw_input("python2: ")
3.res=input("python2: ")
1,2无论接收何种输入,都被存为字符串赋值给res,
3的意思是,用户输入何种类型,就以何种类型赋值给res
- 在python3中 input:用户输入任何值,都存成字符串类型
1.1文件头
#!/usr/bin/env python #Linux系统下有效
# -*- coding: utf-8 -*-
1.2注释
注释当前行:#
注释多行\'\'\'
被注释内容
\'\'\'
1.3执行脚本传入参数
Python有大量的模块,从而使得开发Python程序非常简洁。类库有包括三中:
- Python内部提供的模块
- 业内开源的模块
- 程序员自己开发的模块
Python内部提供一个 sys 的模块,其中的 sys.argv 用来捕获执行执行python脚本时传入的参数
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import sys 5 6 print sys.argv
执行
C:\\Users\\Administrator>python D:\\python_test\\hello.py arg1 arg2 arg3 [\'D:\\\\python_test\\\\hello.py\', \'arg1\', \'arg2\', \'arg3\']
1.4了解pyc文件
执行Python代码时,如果导入了其他的 .py 文件,那么,执行过程中会自动生成一个与其同名的 .pyc 文件,该文件就是Python解释器编译之后产生的字节码。
ps:代码经过编译可以产生字节码;字节码通过反编译也可以得到代码。
range
- range用来指定范围,生成指定的数字。
1
2
3
4
5
6
7
|
for item in range ( 5 , 10 , 2 ): print (item) """ 5 7 9 """ |
基本数据类型
- 数据即变量的值,变量的是用来反映/保持状态以及状态变化的,毫无疑问针对不同的状态就应该用不同类型的数据去标识
一、数字
定义:a=1
特性:
1.只能存放一个值
2.一经定义,不可更改
3.直接访问
分类:整型,长整型,布尔,浮点,复数
1.1整形
- 定义:age=10 #age=int(10)
- 用于标识:年龄,等级,身份证号,qq号,个数
Python的整型相当于C中的long型,Python中的整数可以用十进制,八进制,十六进制表示。
>>> 10 10 --------->默认十进制 >>> oct(10) \'012\' --------->八进制表示整数时,数值前面要加上一个前缀“0” >>> hex(10) \'0xa\' --------->十六进制表示整数时,数字前面要加上前缀0X或0x
python2.*与python3.*关于整型的区别
python2.*
在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647
在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1,即-9223372036854775808~9223372036854775807
python3.*整形长度无限制
1.2长整形long
python2.*:
跟C语言不同,Python的长整型没有指定位宽,也就是说Python没有限制长整型数值的大小,但是实际上由于机器内存有限,所以我们使用的长整型数值不可能无限大。
在使用过程中,我们如何区分长整型和整型数值呢?
通常的做法是在数字尾部加上一个大写字母L或小写字母l以表示该整数是长整型的,例如:
a = 9223372036854775808L
注意,自从Python2起,如果发生溢出,Python会自动将整型数据转换为长整型,
所以如今在长整型数据后面不加字母L也不会导致严重后果了。
python3.*
长整型,整型统一归为整型
1.3布尔bool
True 和 False
1 和 0
1.4浮点数float
- 定义:salary=3.1 #salary=float(3.1)
- 用于标识:工资,身高,体重
Python的浮点数就是数学中的小数,类似C语言中的double。
在运算中,整数与浮点数运算的结果是浮点数
浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,
一个浮点数的小数点位置是可变的,比如,1.23*109和12.3*108是相等的。
浮点数可以用数学写法,如1.23,3.14,-9.01,等等。但是对于很大或很小的浮点数,
就必须用科学计数法表示,把10用e替代,1.23*109就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的而浮点数运算则可能会有四舍五入的误差。
1.5复数complex
复数由实数部分和虚数部分组成,一般形式为x+yj,其中的x是复数的实数部分,y是复数的虚数部分,这里的x和y都是实数。
注意,虚数部分的字母j大小写都可以。
>>> 1.3 + 2.5j == 1.3 + 2.5J
True
1.6数字相关内建函数
二、布尔
- 判断一个条件成立时,用True标识,不成立则用False标识
- *****None,0,空(空字符串,空列表,空字典等)三种情况下布尔值为False*****
三、字符串
- 定义:name=\'tom\' #name=str(\'tom\')
- 用于标识:描述性的内容,如姓名,性别,国籍,种族
- 加了引号的字符就是字符串类型,单引号、双引号、多引号都一样,注意单双引号的嵌套
定义:它是一个有序的字符的集合,用于存储和表示基本的文本信息,‘’或“”或‘’‘ ’‘’中间包含的内容称之为字符串
特性:
1.只能存放一个值
2.不可变
3.按照从左到右的顺序定义字符集合,下标从0开始顺序访问,有序
补充:
1.字符串的单引号和双引号都无法取消特殊字符的含义,如果想让引号内所有字符均取消特殊意义,在引号前面加r,如name=r\'l\\thf\'
2.unicode字符串与r连用必需在r前面,如name=ur\'l\\thf\'
1
2
3
4
5
6
7
8
|
s = "watch ,\'套路\'" #多行字符串必须用多引号 msg = \'\'\' 种一棵树最好的时间是十年前,其次是现在。 所有的成功都是你行动以后对你行动的奖励。 \'\'\' print (s) #watch ,\'套路\' print (msg) |
1、字符串常用操作
res=\'hello world \'
移除空白
res=\'hello world \' print(res.strip()) hello world #移除字符串后面的空白
分割
print(res.split()) [\'hello\', \'world\']
长度
res=\'hello world \' print(len(res)) 17
索引
res=\'hello world \' print(res[4]) o
切片
res=\'hello world \' print(res[1:4]) ell
字符串中的搜索和替换:
S.find(substr, [start, [end]]) #返回S中出现substr的第一个字母的标号,如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索
S.index(substr, [start, [end]]) #与find()相同,只是在S中没有substr时,会返回一个运行时错误
S.rfind(substr, [start, [end]]) #返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号
S.rindex(substr, [start, [end]])
S.count(substr, [start, [end]]) #计算substr在S中出现的次数
S.replace(oldstr, newstr, [count]) #把S中的oldstr替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换
S.strip([chars]) #把S中前后chars中有的字符全部去掉,可以理解为把S前后chars替换为None
注:可用于判断字符串是否为空,字符串为空返回False,不为空时返回Ture。
S.lstrip([chars]) #把S中前chars中有的字符去掉
S.rstrip([chars]) #把S中后chars中有的字符全部去掉
S.expandtabs([tabsize]) #把S中的tab字符替换没空格,每个tab替换为tabsize个空格,默认是8个
字符串的分割和组合:
S.split([sep, [maxsplit]]) #以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符
S.rsplit([sep, [maxsplit]])
S.splitlines([keepends]) #把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。
S.join(seq) #把seq代表的序列──字符串序列,用S连接起来
字符串的mapping,这一功能包含两个函数:
String.maketrans(from, to) #返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。
S.translate(table[,deletechars]) # 使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果S为unicode字符串,那么就不支持 deletechars参数,可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译 表。
字符串中字符大小写的变换:
S.lower() #小写
S.upper() #大写
S.swapcase() #大小写互换
S.capitalize() #首字母大写
String.capwords(S) #这是模块中的方法。它把S用split()函数分开,然后用capitalize()把首字母变成大写,最后用join()合并到一起
S.title() #只有首字母大写,其余为小写,模块中没有这个方法
字符串的测试函数
这些函数返回的都是bool值
S.starstwith(prefix[,start[,end]]) #是否以prefix开头
S.endswith(suffix[,start[,end]]) #以suffix结尾
S.isalnum() #是否全是字母和数字,并至少有一个字符
S.isalpha() #是否全是字母,并至少有一个字符
S.isdigit() #是否全是数字,并至少有一个字符
S.isspace() #是否全是空白字符,并至少有一个字符
S.islower() #S中的字母是否全是小写
S.isupper() #S中的字母是否便是大写
S.istitle() #S是否是首字母大写的
字符串在输出时的对齐:
S.ljust(width,[fillchar]) #输出width个字符,S左对齐,不足部分用fillchar填充,默认的为空格。
S.rjust(width,[fillchar]) #右对齐
S.center(width, [fillchar]) #中间对齐
S.zfill(width) #把S变成width长,并在右对齐,不足部分用0补足
格式化字符串:
s=\'name:{},age:{},sex:{}\'
print(s.format(\'ogen\',18,\'male\',\'asdasda\'))#多余的参数不会影响结果,少参数会报错。
四、列表
定义:[]内以逗号分隔,按照索引,存放各种数据类型,每个位置代表一个元素。
特性:
1.可存放多个值。
2.可修改指定索引位置对应的值,可变。
3.按照从左到右的顺序定义列表元素,下标从0开始顺序访问,有序。
1、列表创建
list_test=[\'lhf\',12,\'ok\']
或
list_test=list(\'abc\')
或
list_test=list([\'lhf\',12,\'ok\'])
2、列表常用操作
>>> classmates = [\'Michael\', \'Bob\', \'Tracy\']
>>> classmates
[\'Michael\', \'Bob\', \'Tracy\']
索引
>>> classmates[0]
\'Michael\'
>>> classmates[1]
\'Bob\'
>>> classmates[2]
\'Tracy\'
>>> classmates[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> classmates[-1]
\'Tracy\'
切片
>>> classmates[0:]
[\'Michael\', \'Bob\', \'Tracy\']
>>> classmates[0::2]
[\'Michael\', \'Tracy\']
>>> classmates[:2]
[\'Michael\', \'Bob\']
>>> classmates[-2:-1]
[\'Bob\']
>>> classmates[-2:0]
[]
>>> classmates[-3:-1]
[\'Michael\', \'Bob\']
追加
>>> classmates.append(\'Adam\')
>>> classmates
[\'Michael\', \'Bob\', \'Tracy\', \'Adam\']
>>> classmates.insert(1, \'Jack\')
>>> classmates
[\'Michael\', \'Jack\', \'Bob\', \'Tracy\', \'Adam\']
删除
>>> classmates.pop()
\'Adam\'
>>> classmates
[\'Michael\', \'Jack\', \'Bob\', \'Tracy\']
>>> classmates.pop(1)
\'Jack\'
>>> classmates
[\'Michael\', \'Bob\', \'Tracy\']
长度
>>> len(classmates)
3
循环
>>> for i in classmates:
... print(i)
...
Michael
Bob
Tracy
包含
>>> \'Bob\' in classmates
True
>>> \'ogen\' in classmates
False
1
2
|
students_info = [[ \'tom\' , 18 ,[ \'sing\' ,]],[ \'rose\' , 18 ,[ \'play\' , \'sleep\' ]]] print (students_info[ 0 ][ 2 ][ 0 ]) #取出第一个学生的第一个爱好 #sing |
五、元组
定义:与列表类似,只不过[]改成()
特性:
1.可存放多个值。
2.不可变。
3.按照从左到右的顺序定义元组元素,下标从0开始顺序访问,有序。
1、元组创建
ages = (11, 22, 33, 44, 55)
或
ages = tuple((11, 22, 33, 44, 55))
定义一个空的元组 t=()
定义只有1个元素的元组
t=(1) 这样t的类型就是整形
t=(1,) 这样t的类型就是元组
一个“可变的”tuple:
>>> t = (\'a\', \'b\', [\'A\', \'B\'])
>>> t[2][0] = \'X\'
>>> t[2][1] = \'Y\'
>>> t
(\'a\', \'b\', [\'X\', \'Y\'])
定义的时候tuple包含的3个元素:
当我们把list的元素\'A\'
和\'B\'
修改为\'X\'
和\'Y\'
后,tuple变为:
表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的“不变”是说,tuple的每个元素,指向永远不变。即指向\'a\'
,就不能改成指向\'b\'
,指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!
2、元组的操作
索引
>>> ages = (11, 22, 33, 44, 55)
>>> ages[0]
11
切片
>>> ages[0:]
(11, 22, 33, 44, 55)
>>> ages[0:3]
(11, 22, 33)
>>> ages[:3]
(11, 22, 33)
>>> ages[:3:2]
(11, 33)
>>> ages[-3:-1]
(33, 44)
循环
>>> for i in ages:
... print(i)
...
11
22
33
44
55
包含
>>> 11 in ages
True
>>> 12 in ages
False
六、字典
定义:{key1:value1,key2:value2},key-value结构,key必须可hash
特性:
1.可存放多个值。
2.可修改指定key对应的值,可变。
3.无序。
1、字典的创建
person = {"name": "sb", \'age\': 18}
或
person = dict(name=\'sb\', age=18)
person = dict({"name": "sb", \'age\': 18})
person = dict(([\'name\',\'sb\'],[\'age\',18]))
{}.fromkeys(seq,100) #不指定100默认为None
注意:
>>> dic={}.fromkeys([\'k1\',\'k2\'],[])
>>> dic
{\'k1\': [], \'k2\': []}
>>> dic[\'k1\'].append(1)
>>> dic
{\'k1\': [1], \'k2\': [1]}
2、字典的操作
索引
>>> d = {\'Michael\': 95, \'Bob\': 75, \'Tracy\': 85}
>>> d[\'Michael\']
95
新增
>>> d[\'alex\']=100
>>> d
{\'Michael\': 95, \'Bob\': 75, \'Tracy\': 85, \'alex\': 100}
如果key不存在,就会报错。
避免key不存在的错误,有两种判断key是否存在的方式
1.通过in判断:
>>> \'Thomas\' in d
False
2.通过get()判断,如果key不存在,可以返回None,或者自己指定的value:
>>> d.get(\'Thomas\')
>>> d.get(\'Thomas\', -1)
-1
删除
>>> d.pop(\'Bob\')
75
>>> d
{\'Michael\': 95, \'Tracy\': 85}
循环
>>> for i in d:
... print(i,d[i])
...
Michael 95
Bob 75
Tracy 85
alex 100
长度
>>> len(d)
4
请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多。
而list相反:
- 查找和插入的时间随着元素的增加而增加;
- 占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
3、字典的常用函数
.pop(key,\'str\') 删除key对应的键值对,返回value。key不存在返回str。
.popitem() 随机删除键值对
.keys() 返回字典的所有key到dict_keys中。可以使用list(d.keys())
.values() 返回字典的valu到dict_values中,可以使用list(d.keys())
.items() 返回键值对。
.get(key,\'str\') 返回key对应的值value,key不存在返回自定义的str。
.clear() 清空字典
.copy() 复制字典
{}.fromkeys([],None) 初始化字典
.update(dict) 将新字典ditct更新到原字典中,键存在覆盖值,键不存在创建键值对
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
info = { \'name\' : \'tom\' , \'hobbies\' :[ \'sing\' , \'sleep\' ], \'company\' :{ \'name\' : \'google\' , \'type\' : \'it\' , \'fund\' : 8000000000 , } } print (info[ \'company\' ][ \'fund\' ]) #取公司现金储备 #8000000000 students = [ { \'name\' : \'tom\' , \'age\' : 18 , \'hobbies\' :[ \'sing\' , \'play\' ]}, { \'name\' : \'rose\' , \'age\' : 88 , \'hobbies\' :[ \'read\' , \'sleep\' ]}, { \'name\' : \'jack\' , \'age\' : 99 , \'hobbies\' :[ \'swim\' , \'watchTV\' , \'talk\' ]}, ] print (students[ 2 ][ \'hobbies\' ][ 1 ]) #取第3个学生的第2个爱好watchTV |
流程控制之if...else
1
2
3
4
5
6
7
8
9
10
11
12
|
""" rose --> 超级管理员 tom --> 普通管理员 其他 --> 普通用户 """ name = input ( \'请输入用户名字:\' ).strip() if name = = \'rose\' : print ( \'超级管理员\' ) elif name = = \'tom\' : print ( \'普通管理员\' ) else : print ( \'普通用户\' ) |
流程控制之while循环
一、条件循环
1
2
3
4
5
|
count = 0 while count < = 10 : if count % 2 = = 0 : print ( \'loop\' ,count) count + = 1 |
二、死循环
1
2
|
while True : print ( \'hello world\' ) |
三、循环嵌套与tag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
name = \'tom\' password = \'123\' tag = True while tag: inp_name = input ( \'用户名: \' ).strip() inp_pwd = input ( \'密码: \' ).strip() if inp_name = = name and inp_pwd = = password: while tag: cmd = input ( \'>>: \' ) if not cmd: continue if cmd = = \'q\' : |