一,公共知识
1.第一个小程序(参考)
from tkinter import *
from tkinter import messagebox
def songhua(e):
messagebox.showinfo("Message","给你一朵小红花")
print("送花")
root = Tk()
root.title("我的第一个GUI程序")
root.geometry("500x300+100+200")
btn1 = Button(root)
btn1["text"] = "演示点击"
btn1.pack()
btn1.bind("",songhua)
root.mainloop()
2.类对象方式创建窗口(推荐该方式)
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.btn1 =Button(self)
self.btn1["text"] = "点击送花"
self.btn1.pack()
self.btn1["command"] = self.songhua
self.btn_quit = Button(self,text = "退出程序",command = self.master.destroy)
self.btn_quit.pack()
def songhua(self):
messagebox.showinfo("送花","送你99朵花")
root = Tk()
root.geometry("400x100+100+300")
root.title("一个经典的gui程序类")
app = Application(master = root)
root.mainloop()
3.三种控件布局方式
(1)pack布局
"""
tkinter中提供的布局管理器有三种:pack(水平/垂直排列),grid(网格排列),place(像素位置部署,更精确)
一,grid布局
采用表格结构组织组件,子组件位置由行和列的单元格来确定,并且可以跨行和跨列。
选项 说明 取值范围
column 单元格列号 从0开始的正整数
colunmspan 跨越的列数 正整数
row 单元格行号 从0开始的正整数
rowspan 跨越的行数 正整数
ipadx,ipady 设置子组件之间的间隔 非负浮点数,默认0.0
x/y方向,单位为像素
padx,pady 与之并列的组件之间的间隔 非负浮点数,默认0.0
x/y方向,单位为像素
sticky 组件紧贴所在单元格的某一角 n,s,w,e,nw,sw,se,ne,center(默认)
"""
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.label1 = Label(self,text = "用户名")
self.label1.grid(row = 0,column = 0)
self.entry1 = Entry(self)
self.entry1.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)
root = Tk()
root.geometry("400x400+100+300")
app = Application(master = root)
root.mainloop()
(2)grid布局
"""
二,pack布局管理器
按照垂直或者水平的方向自然排布,默认为在父组件中自顶向下垂直添加组件。
选项 说明 取值范围
side 定义组件靠在父组件的哪一边上 top,botton.left.right,默认为top
ipadx,ipady 设置子组件之间的间隔 非负浮点数,默认0.0
x/y方向,单位为像素
padx,pady 与之并列的组件之间的间隔 非负浮点数,默认0.0
x/y方向,单位为像素
anchor 对齐方式(w--左对齐,e--右对齐,n--顶对齐,s--底对齐) n,s,w,e,nw,sw,se,ne,center(默认)
"""
from tkinter import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
f1 = Frame(self)
f1.pack()
f2 = Frame(self).pack()
btnText = ["流行风","中国风","日本风","重金属","轻音乐"]
for txt in btnText:
Button(f1,text = txt).pack(side = "left",padx = "10")
for i in range(1,20):
Label(f2,width = 5,height = 10,borderwidth = 1,relief = "solid",bg = "black" if i%2 ==0 else "white").pack(side = "left",padx = 2)
root = Tk()
root.geometry("700x220")
app = Application(master = root)
root.mainloop()
(3)place布局(感觉不太好用)
"""
三,place布局管理器
通过坐标精确控制组件的位置,适用于一些布局更加灵活的场景。
选项 说明 取值范围
x,y 组件左上角相对于窗口的绝对位置 非负整数
relx,rely 组件最上角相对于父组件的相对位置 relx:0--最左边,0.5--正中间,1--最右边
rely:0--最上边,0.5--正中间,1--最下边
relwidth,relheight 组件的宽度和高度(相对于父容器) 非负整数
anchor 对齐方式(w--左对齐,e--右对齐,n--顶对齐,s--底对齐) n,s,w,e,nw,sw,se,ne,center(默认)
"""
from tkinter import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack(fill="both", expand=True)
self.creatWidget()
def creatWidget(self):
"""创建组件"""
f1 = Frame(self,width = 200,height = 200,bg = "green")
f1.place(x = 30,y = 30)
Button(self,text = "你好吗").place(relx = 0.2,x = 100,y = 20,relwidth = 0.2,relheight = 0.5)
Button(f1,text = "你真的很好").place(relx = 0.6,rely = 0.7)
Button(f1,text = "你的老师").place(relx = 0.5,rely = 0.2)
root = Tk()
root.geometry("500x300")
root.title("布局管理器place")
root["bg"] = "white"
app = Application(master = root)
root.mainloop()
4.多种控件事件绑定方式
"""
一,通过组件对象绑定
1.通过command属性绑定(适合简单不需要获取event的对象) Button(root,text = "登录",command = login)
2.通过bind()方法绑定 c1= Canvas();c1.bind("",drawLine)
二,组件类的绑定
1.调用对象的bind_class 函数,将同类组件都绑定上事件 btn1.bind_class("Button","",func)
"""
from tkinter import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def mouseTest1(self,event):
print("bind()方式绑定,可以获取event对象")
print(event.widget)
def mouseTest2(self, a,b):
print("a = {0},b = {1}".format(a,b))
print("command方式绑定,不能直接获取event对象")
def mouseTest3(self,event):
print("右键单击事件,绑定所有的按钮控件")
print(event.widget)
def creatWidget(self):
"""创建组件"""
b1 = Button(self,text = "测试bind方法")
b1.pack(side = "left")
b1.bind("",self.mouseTest1)
b2 = Button(self,text = "测试command方法",command = lambda : self.mouseTest2("songjian","guo"))
b2.pack(side = "left")
b1.bind_class("Button", "", self.mouseTest3)
root = Tk()
root.geometry("270x50")
app = Application(master = root)
root.mainloop()
5.常见事件学习
"""
所有的组件都可以通过 组件.bind(event,handler) 的方式来绑定事件
鼠标和键盘事件
代码 说明
鼠标左键按下,2表示中键,3表示右键
<1>
鼠标左键释放
按住鼠标左键移动
双击左键
鼠标指针进入某一组件区域
鼠标指针离开某一组件区域
滚动滚轮
按下a键,a可用其他键代替
释放a键
按下A键,可用其他代替
同事按下alt和a,alt可用ctrl和shift替代
快速按下两下a
同时按下CTRL和V键,V可以被替代
常用event对象属性
名称 说明
char 按键字符,仅对键盘事件有效
keycode 按键编码,仅对键盘事件有效
keysym 按键名称,仅对键盘事件有效(在系统中的代表名)
num 鼠标按键,仅对鼠标事件有效
type 所触发的事件类型
widget 引发事件的组件
width,height 组件改变后的大小,仅Configure有效
x,y 鼠标当前位置,相对于父容器
x_root,y_root 鼠标当前位置,相对于整个屏幕
"""
from tkinter import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def mouseTest(self,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(self,event):
self.c1.create_oval(event.x,event.y,event.x+1,event.y+1)
def keyboardTest(self,event):
print("键的keycode:{0},键的char:{1},键的keysym{2}".format(event.keycode,event.char,event.keysym))
def press_a_test(self,event):
print("press a")
def release_a_test(self,event):
print("release a")
def creatWidget(self):
"""创建组件"""
self.c1 = Canvas(self,width = 200,height = 200,bg = "green")
self.c1.pack()
self.c1.bind("",self.mouseTest)
self.c1.bind("",self.testDrag)
self.master.bind("",self.keyboardTest)
self.master.bind("",self.press_a_test)
self.master.bind("",self.release_a_test)
root = Tk()
root.geometry("530x300")
app = Application(master = root)
root.mainloop()
6.通过 lambda 给处理函数传参
from tkinter import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def mouseTest1(self):
print("command方式,简单情况:不设置获取event对象,可以使用")
def mouseTest2(self, a,b):
print("a = {0},b = {1}".format(a,b))
def creatWidget(self):
"""创建组件"""
Button(self,text = "测试command1",command = self.mouseTest1).pack(side = "left")
Button(self, text="测试command2", command=lambda: self.mouseTest2("songjian","guo")).pack(side="left")
root = Tk()
root.geometry("270x50")
app = Application(master = root)
root.mainloop()
二,控件学习
1.常用组件汇总
2.常见组件Option选项(设置方法/常见参数)
"""
option选项的三种设置方式
1.创建对象是,使用命名参数设置
new = Button(self,fg = "red",bg = "blue")
2.创建对象后,使用字典索引形式设置
new["fg"] = "red"
3.创建对象后,使用config()方法设置
new.config(fg = "red",bg = "blue")
option选项
activebackground--指定组件处于激活状态时的背景色
activeforeground--指定组件处于激活状态时的前景色
anchor--指定组件内内容的显示位置:N,NE,E,SE,S,SW,W,NW,CENTER.比如:NW(North West)
background(gd)--指定组件正常显示时的背景色
bitmap--指定在组件上显示该选型指定的位图
borderwidth--指定组件显示3D边框的宽度
cursor--指定光标在组件上的样式
command--指定组件相关联的命令方法
font--指定组件上显示的文本字体
foreground(fg)--指定组件正常显示时的前景色
highlightbackground--指定组件在高亮状态下的背景色
highlightcolor--指定组件在高亮状态下的前景色
highlightthickness--指定组件在高亮状态下的周围方形区域的宽度
height--指定组件高度,至少为1
image--指定组件中显示的图像,其会覆盖text,bitmap选项指定的内容
justify--指定组件内部内容的对齐方式:LEFT(左对齐),CENTER(居中对齐),RIGHT(右对齐)
padx--指定组件内部在水平方向上两边的空白
pady--指定组件内部在垂直方向上两边的空白
relief--指定组件的3D效果,该选项支持的值包括RAISED,SUNKEN,FLAT,RIDGE,SOLID,GROOVE
该值指出组件内部相对于外部的外观样式。比如RAISED表示组件内部相对于外部凸起
selectbackground--指定组件在选中状态下的背景色
selectborderwidth--指定组件在选中状态下的3D边框宽度
selectforeground--指定组件在选中状态下的前景色
state--指定组件的当前状态。NORMAL(正常),DISABLE(禁用)
takefocus--指定组件在键盘遍历(Tab或Shift+Tab)时是否接收焦点,1--接收焦点 0--不接收焦点
text--指定组件上显示的文本
textvariable--指定一个变量名,通过该属性获得组件字符内容
underline--指定为组件文本的第几个字符添加下划线,该选项就相当于为组件绑定了快捷键
width--指定组件宽度,至少为1
wraplength--对于能支持字符换行的组件,该选项指定每行显示的最大字符数,
超过该数量的字符将会转到下行显示
xscrollcommand--通常用于将组件的水平滚动改变(包括内容滚动或高度发生改变)
与水平滚动条的set方法关联。从而让组件的水平滚动改变传递到水平滚动条
yscrollcommand--通常用于将组件的垂直滚动改变(包括内容滚动或高度发生改变)
与垂直滚动条的set方法关联。从而让组件的垂直滚动改变传递到垂直滚动条
"""
3.Lbel控件(信息展示)
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.label1 = Label(self,text = "Label测试",width = 10,height = 2,bg = "black",fg = "white")
self.label1.pack()
self.label2 = Label(self,text = "字体测试",width = 10,height = 2,bg = "blue",fg = "white",font = ("黑体",30))
self.label2.pack()
global photo
photo = PhotoImage(file = "图片1.gif")
self.label3 = Label(self,text = "图片显示",image = photo)
self.label3.pack()
self.label4 = Label(self,text = "多行文本1\n多行文本2\n多行文本3\n",borderwidth = 1,relief = "solid",justify = "right")
self.label4.pack()
def songhua(self):
messagebox.showinfo("送花","送你99朵花")
root = Tk()
root.geometry("400x400+100+300")
root.title("测试Label")
app = Application(master = root)
root.mainloop()
4.Button控件(按钮)
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.btn1 = Button(self,text = "登录",width = 6,height = 3,anchor = E,command = self.login)
self.btn1.pack()
global photo
photo = PhotoImage(file = "图片1.gif")
self.btn2 = Button(self,image = photo,command = self.login)
self.btn2.pack()
def login(self):
messagebox.showinfo("送花","送你99朵花")
root = Tk()
root.geometry("400x400+100+300")
root.title("测试Button")
app = Application(master = root)
root.mainloop()
5.Entry控件(单行文本框)
"""
Entry用来接收一行字符串的控件,如果用户输入的文字长度长于Entry控件
的宽度时,文字会自动向后滚动,如果想输入多行文本,需要使用Text控件。
"""
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.label1 = Label(self,text = "用户名")
self.label1.pack()
v1 = StringVar()
self.entry1 = Entry(self,textvariable = v1)
self.entry1.pack()
self.label2 = Label(self,text = "密码")
self.label2.pack()
v2 = StringVar()
self.entry2 = Entry(self,textvariable = v2,show = "*")
self.entry2.pack()
self.btn1 = Button(self,text = "登录",command = self.login)
self.btn1.pack()
def login(self):
print("输入的用户名为" + self.entry1.get())
print("输入的密码为" + self.entry2.get())
messagebox.showinfo("送花","送你99朵花")
root = Tk()
root.geometry("400x400+100+300")
root.title("测试Entry")
app = Application(master = root)
root.mainloop()
6.Text控件(多行文本框)
"""
Text主要用于显示多行文本,还可以显示网页连接,图片,HTML页面,CSS样式表。
常被用作简单的文本处理器,文本编辑器或者网页浏览器。
"""
from tkinter import *
from tkinter import messagebox
import webbrowser
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.w1 = Text(root,width = 40,height = 12,bg = "gray")
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):
self.w1.insert(INSERT,"gaoqi")
self.w1.insert(END,"[sxt]")
def returnText(self):
print(self.w1.get(1.2,1.6))
print("所有文本内容:\n" + self.w1.get(1.0,END))
def addImage(self):
self.photo = PhotoImage(file = "图片1.gif")
self.w1.image_create(END,image = self.photo)
def addWidget(self):
b1 = Button(self.w1,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\ngood潍坊建国学堂\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.2)
self.w1.tag_config("baidu",underline = True)
self.w1.tag_bind("baidu","",self.webshow)
def webshow(self,event):
webbrowser.open("http://www.baidu.com")
root = Tk()
root.geometry("400x400+100+300")
root.title("测试Text")
app = Application(master = root)
root.mainloop()
7.Radiobutton控件(组单选按钮)
"""
Entry用来接收一行字符串的控件,如果用户输入的文字长度长于Entry控件
的宽度时,文字会自动向后滚动,如果想输入多行文本,需要使用Text控件。
"""
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(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())
root = Tk()
root.geometry("400x400+100+300")
app = Application(master = root)
root.mainloop()
8.Checkbutton控件(组复现按钮)
"""
Entry用来接收一行字符串的控件,如果用户输入的文字长度长于Entry控件
的宽度时,文字会自动向后滚动,如果想输入多行文本,需要使用Text控件。
"""
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
self.codeHobby = IntVar()
self.videoHobby = IntVar()
print(self.codeHobby.get())
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("测试","选择了敲代码")
root = Tk()
root.geometry("400x400+100+300")
app = Application(master = root)
root.mainloop()
9.Optionmenu控件(菜单选项)
from tkinter import *
root = Tk()
root.geometry("200x100")
v = StringVar(root)
v.set("打开查看选项")
om = OptionMenu(root,v,"选项一","选项二","选项三")
om["width"] = 10
om.pack()
def test1():
print("选择的选型为:",v.get())
Button(root,text = "确定",command = test1).pack()
root.mainloop()
10.Scale控件(滑块)
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,tickinterval = 5,orient = HORIZONTAL,command = test1)
s1.pack()
a = Label(root,text = "好好学习",width = 10,height = 1,bg = "black",fg = "white")
a.pack()
root.mainloop()
11.Askcolor控件(颜色选择框)
from tkinter import *
from tkinter.colorchooser import *
root = Tk()
root.geometry("400x150")
def test1():
s1 = askcolor(color = "red",title = "选择背景色")
print(s1)
root.config(bg = s1[1])
Button(root,text = "选择背景色",command =test1).pack()
root.mainloop()
12.弹出消息框控件
"""
一,简单消息框
simpledialog(简单对话框)包含以下函数
函数名 说明
askfloat(title,prompt,**kw) 输入并返回浮点数
askinteger(title,prompt,**kw) 输入并返回整数
askstring(title,prompt,**kw) 输入并返回字符串
title--窗口标题 prompt--提示信息 kw为各种选项:initialvalue(初始值),minvalue(最小值),maxvalue(最大值)
"""
from tkinter.simpledialog import *
root = Tk()
root.geometry("400x100")
def test1():
a = askinteger(title = "输入年龄",prompt="请输入年龄",initialvalue = 18,minvalue = 1,maxvalue = 150)
show["text"] = a
Button(root,text = "选择文本文件",command =test1).pack()
show = Label(root,width = 40,height = 3,bg = "green")
show.pack()
root.mainloop()
"""
二,通用消息框
"""
from tkinter import *
from tkinter.messagebox import *
root = Tk()
root.geometry("400x100")
a1 = showinfo(title="宋建国", message="好好学习,天天洗脚\就是浪")
print(a1)
root.mainloop()
13.文件对话框(文件操作)
""""
帮助我们实现可视化的操作目录,文件。
函数名 对话框 说明
askopenfilename(**options) 文件对话框 返回打开的文件名
askopenfilenames(**options) 文件对话框 返回打开的多个文件名列表
askopenfile(**options) 文件对话框 返回打开文件对象
askopenfiles(**options) 文件对话框 返回打开的文件对象列表
askdirectory(**options) 目录对话框 返回目录名
asksaveasfile(**options) 保存对话框 返回保存的文件对象
asksaveasfilename(**options) 保存对话框 返回保存的文件名
options
参数名 说明
defaultextension 默认后缀,没有输入则自动添加
filetypes = [(label1,pattern1),(label2,pattern2)] 文件显示过滤器
initaldir 初始目录
initalfile 初始文件
parent 父窗口
title 窗口标题
"""
from tkinter import *
from tkinter.filedialog import *
root = Tk()
root.geometry("400x100")
def test1():
f = askopenfilename(title = "上传文件",initialdir = "C:/Users/Administrator/Desktop/Tkinter/尚学堂",filetypes = [("图片文件",".gif")])
show["text"] = f
Button(root,text = "选择图片",command =test1).pack()
show = Label(root,width = 40,height = 3,bg = "green")
show.pack()
root.mainloop()
from tkinter import *
from tkinter.filedialog import *
root = Tk()
root.geometry("400x100")
def test1():
f = askopenfile(title = "上传文件",initialdir = "d:",filetypes = [("文本文件",".txt")])
show["text"] = f.read()
Button(root,text = "选择文本文件",command =test1).pack()
show = Label(root,width = 40,height = 3,bg = "green")
show.pack()
root.mainloop()
三,项目知识深化
1.【案例一】计算器界面实现
from tkinter import *
from tkinter import messagebox
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.pack()
self.creatWidget()
def creatWidget(self):
"""创建组件"""
btnText = (
("MC","M+","M-","MR"),
("C","±","/","x"),
(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,columnspan = 2,column = cindex,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)
root = Tk()
root.geometry("200x250+200+300")
app = Application(master = root)
root.mainloop()
2.【案例二】菜单界面实现
from tkinter.filedialog import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.textpad = None
self.pack()
self.creatWidget()
def creatWidget(self):
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)
menuFile.add_command(label = "新建",accelerator = "ctrl+n",command = self.test)
menuFile.add_command(label="打开", accelerator="ctrl+o", command=self.test)
menuFile.add_command(label="保存", accelerator="ctrl+s", command=self.test)
menuFile.add_separator()
menuFile.add_command(label = "退出",accelerator = "strl+q",command = self.test)
root["menu"] = menubar
self.textpad = Text(root,width = 50,height = 30)
self.textpad.pack()
self.contextMenu = Menu(root)
self.contextMenu.add_command(label = "背景颜色",command = self.test)
root.bind("",self.createContextMenu)
def test(self):
pass
def createContextMenu(self,event):
self.contextMenu.post(event.x_root,event.y_root)
if __name__ == '__main__':
root = Tk()
root.geometry("450x300+200+300")
root.title("好好学习")
app = Application(master = root)
root.mainloop()
3.【案例三】记事本项目
import tkinter as tk
from tkinter.filedialog import *
from tkinter.colorchooser import *
class Application(Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
self.textpad = None
self.pack()
self.creatWidget()
def creatWidget(self):
menubar = Menu(self,tearoff = False)
menuFile = Menu(menubar,tearoff = False)
menuEdit = Menu(menubar,tearoff = False)
menuHelp = Menu(menubar,tearoff = False)
menubar.add_cascade(label = "文件(F)",menu = menuFile)
menubar.add_cascade(label="编辑(E)", menu=menuEdit)
menubar.add_cascade(label="帮助(H)", menu=menuHelp)
menuFile.add_command(label = "新建",accelerator = "ctrl+n",command = self.newfile)
menuFile.add_command(label="打开", accelerator="ctrl+o", command=self.openfile)
menuFile.add_command(label="保存", accelerator="ctrl+s", command=self.savefile)
menuFile.add_separator()
menuFile.add_command(label = "退出",accelerator = "strl+q",command = self.exit)
self.master["menu"] = menubar
self.master.bind("",lambda event:self.newfile())
self.master.bind("",lambda event:self.openfile())
self.master.bind("", lambda event: self.savefile())
self.master.bind("", lambda event: self.quit())
status_str_var = tk.StringVar()
status_str_var.set("字符数{0}".format(0))
self.status_label = tk.Label(self,textvariable = status_str_var,bd = 1,relief = tk.SUNKEN,anchor = tk.W)
self.status_label.pack(side = tk.BOTTOM,fill = tk.X)
self.textpad = Text(self,width = 60,height = 30)
self.textpad.pack()
self.contextMenu = Menu(self)
self.contextMenu.add_command(label = "背景颜色",command = self.bgColor)
self.master.bind("",self.createContextMenu)
def openfile(self):
self.textpad.delete("1.0","end")
temp_filename = askopenfilename(title="打开文件")
try:
with open(temp_filename, encoding='utf-8') as f:
self.textpad.insert(INSERT,f.read())
self.filename = f.name
except:
print("文本格式发生错误")
with open(temp_filename) as f:
self.textpad.insert(INSERT,f.read())
self.filename = f.name
def savefile(self):
print(self.textpad.get(1.0,END))
with open(self.filename,"w") as f:
c = self.textpad.get(1.0,END)
f.write(c)
def newfile(self):
self.filename = asksaveasfilename(title = "另存为",initialfile = "未命名.txt",filetypes = [("文本文档","*.txt")],defaultextension = ".txt")
self.savefile()
def bgColor(self):
s1 = askcolor(color="red", title="选择背景色")
self.textpad.config(bg=s1[1])
def exit(self):
self.quit()
def createContextMenu(self,event):
self.contextMenu.post(event.x_root,event.y_root)
if __name__ == '__main__':
root = Tk()
root.geometry("450x300+200+300")
root.title("好好学习")
app = Application(master = root)
root.mainloop()
4.【案例四】简单图片浏览器(实现jpg格式图片显示)
import tkinter as tk
import glob
from PIL import Image,ImageTk
root = tk.Tk()
root.geometry("900x650+100+100")
root.title("图片查看器")
photos = glob.glob("./input/*.jpg")
photos = [ImageTk.PhotoImage(Image.open(photo)) for photo in photos]
current_photo_no = 0
photo_label = tk.Label(root,image = photos[current_photo_no],width = 900,height = 600)
photo_label.pack()
number_var = tk.StringVar()
number_var.set("1 of 2")
tk.Label(root,textvariable = number_var,bd = 1,relief = tk.SUNKEN,anchor = tk.CENTER).pack(fill = tk.X)
button_frame = tk.Frame(root)
button_frame.pack()
prev_photo = tk.Button(button_frame,text = "上一页")
next_photo = tk.Button(button_frame,text = "下一页")
prev_photo.pack(side = tk.LEFT,anchor = tk.CENTER)
next_photo.pack(side = tk.RIGHT,anchor = tk.CENTER)
def change_photos(next_no):
global current_photo_no
current_photo_no += next_no
if current_photo_no >=len(photos):
current_photo_no = 0
if current_photo_no < 0:
current_photo_no = len(photos) - 1
number_var.set(f"{current_photo_no+1} of {len(photos)}")
photo_label.configure(image = photos[current_photo_no])
prev_photo.config(command = lambda : change_photos(-1))
next_photo.config(command = lambda : change_photos(1))
root.mainloop()
5.【案例五】学生信息管理系统(综合应用)