Python-GUI
from tkinter import * from tkinter import messagebox root=Tk() btn01=Button(root)#把按钮放在窗口里面 btn01['text']='点我就送花' btn01.pack()#压缩一下 def songhua(e): #e就是事件对象 messagebox.showinfo('Message','送你一朵玫瑰花,亲亲我吧') #Message是标题 print('送你99朵玫瑰花') btn01.bind('<Button-1>',songhua) root.mainloop() #调用组件的mainloop()方法,进入事件循环 #产生一个空白窗口
效果图:
- 对屏幕的大小和位置进行设置
geometry('wxh±x±y')w为宽度 h为高度 +x为距屏幕左边的距离 -x为距屏幕右边的距离 +y为距离屏幕上边的距离 -y为距离屏幕下边的距离
from tkinter import * from tkinter import messagebox root=Tk() root.title('我的第一个GUI程序') root.geometry('500x300+100+200') #geometry('wxh±x±y')w为宽度 h为高度 +x为距屏幕左边的距离 -x为距屏幕右边的距离 +y为距离屏幕上边的距离 -y为距离屏幕下边的距离 btn01=Button(root)#把按钮放在窗口里面 btn01['text']='点我就送花' btn01.pack()#压缩一下 def songhua(e): #e就是事件对象 messagebox.showinfo('Message','送你一朵玫瑰花,亲亲我吧') #Message是标题 print('送你99朵玫瑰花') btn01.bind('<Button-1>',songhua) root.mainloop() #调用组件的mainloop()方法,进入事件循环 #产生一个空白窗口
效果图:
- 使用面向对象的方式来写GUI程序
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 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朵玫瑰花') # Message是标题 root=Tk() root.geometry('500x300+100+200') root.title('我的第一个GUI程序') app =Application(master=root) root.mainloop() #调用组件的mainloop()方法,进入事件循环 #产生一个空白窗口
效果图:
- Label(标签)主要用于显示文本信息,也可以显示图像
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): # 创建组件 self.label01=Label(self,text='标签1',width=10,height=2, bg='black',fg='white')#bg是背景色 fg是前景色 self.label01.pack() self.label02 = Label(self, text='标签2', width=10, height=2, bg='blue', fg='white',font=('黑体',30)) # bg是背景色 fg是前景色 self.label02.pack() #显示图像 tkinter只支持gif格式 global photo #把photo声明成全局变量,如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出图像 photo =PhotoImage(file='img1.gif') self.label03 = Label(self, image=photo) self.label03.pack() self.label04 = Label(self, text='标签4\n显示多行图片\n2021-2-7\n', borderwidth=5,relief='solid',justify='right') #加了边界 边界宽度 效果 右对齐 self.label04.pack() def songhua(self): messagebox.showinfo('送花', '送你99朵玫瑰花') # Message是标题 if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Label测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- Button按钮组件
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): # 创建组件 self.btn01=Button(root,text='登录',command=self.login) self.btn01.pack() self.btn02 = Button(root, text='登录2', width=6,height=3,anchor=NE,command=self.login)#anchor把字放在右上角 self.btn02.pack() global photo #把photo声明成全局变量,如果是局部变量,本方法执行完毕后,图像对象销毁,窗口显示不出图像 photo =PhotoImage(file='img1.gif') self.btn03 = Button(root, image=photo,command=self.login)# 点击图片也会有弹窗出现 self.btn03.pack() self.btn03.config(state='disabled') #设置图片按钮为禁用 def login(self): messagebox.showinfo('按钮系统', '登录成功') # Message是标题 if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Button测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- Entry单行文本框:用来接收一行字符串的控件。如果输入的文字长度大于Entry控件的宽度,文字会自动向后滚动,如果想输入多行文本,需要Text控件
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): # 创建组件 self.label01=Label(self,text='用户名') self.label01.pack() #StringVar变量绑定到指定的组件 #StringVar变量的值发生变化,组件内容也变化 #组件内容发生变化,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() self.btn01=Button(self,text='登录',command=self.login) self.btn01.pack() def login(self): username=self.entry01.get() pwd=self.entry02.get() print('去数据库比对用户名和密码!') print('用户名:'+username) print('密码:' +pwd) if username=='Lijun' and pwd=='lijun19990429': messagebox.showinfo('GUI学习系统','登录成功') else: messagebox.showinfo('GUI学习系统', '登录失败!用户名或密码错误') if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Entry测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- Text多行文本框
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox import webbrowser class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 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') #在第1行第0列插入0123456789然后换行abcdefg 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,'Lijun') #END索引号表示在最后插入 self.w1.insert(END,'[sxt]') 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='img1.gif') self.w1.image_create(END,image=self.photo) def addWidget(self): b1=Button(self.w1,text='GUI界面') #在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!\n浙江理工大学\n厉俊\n百度,搜一下就知道') #插入这段话 self.w1.tag_add('good',1.0,1.9)#添加标记 标记名为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','<Button-1>',self.webshow) def webshow(self,event): webbrowser.open('http://www.baidu.com') if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
按第一个按钮后:
按第二个按钮后:
按第三个按钮后:
按第四个按钮后:
按最后一个按钮后:
- 利用Entry和Text控件输入 然后Text控件进行输出(输入数字 然后+2 或者+10 然后把输出显示到Text上)
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self, master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master = master self.pack() self.createWidget() def createWidget(self): # 创建组件 self.label01 = Label(self, text='输入') self.label01.pack() # 创建组件 # StringVar变量绑定到指定的组件 # StringVar变量的值发生变化,组件内容也变化 # 组件内容发生变化,StringVar变量的值也发生变化 v1 = StringVar() self.entry01 = Entry(self, textvariable=v1) self.entry01.pack() # 创建组件 self.label02 = Label(self, text='第二种') self.label02.pack() # 创建组件 self.w1 = Text(self, width=20, height=2, bg='white') # 宽度20个字母(10个汉字),高度一个行高 self.w1.pack() # 创建组件 self.btn01 = Button(self) self.btn01['text'] = '输入' self.btn01.pack() self.btn01['command'] = self.shuru # 创建组件 self.label02 = Label(self, text='输出') self.label02.pack() # 创建组件 self.btn02 = Button(self) self.btn02['text'] = '输出' self.btn02.pack() self.btn02['command'] = self.shuchu # 创建组件 self.w2 = Text(self, width=20, height=2, bg='white') # 宽度20个字母(10个汉字),高度一个行高 self.w2.pack() def shuru(self): shuru1 = self.entry01.get() messagebox.showinfo('提示', '输入成功') # Message是标题 # def shuchu(self): # shuru1 = int(self.entry01.get()) # #shuru2=int(self.w1.get("0.0", "end")) #获取文本框内容 # shuchu1 = shuru1+2 # self.w2.insert(INSERT, shuchu1) def shuchu(self): shuru1 = self.entry01.get() shuru2 = self.w1.get("0.0", "end") if shuru1=="" and shuru2!='\n': shuchu2 = int(shuru2) + 10 self.w2.delete(1.0, END) self.w2.insert(INSERT, shuchu2) elif shuru2=="\n" and shuru1!="": shuchu1 = int(shuru1) + 2 self.w2.delete(1.0, END) self.w2.insert(INSERT, shuchu1) elif shuru2!="\n" and shuru1!="": shuchu1 = int(shuru1) + 2 shuchu2 = int(shuru2) + 10 self.w2.delete(1.0, END) self.w2.insert(INSERT, shuchu1) self.w2.insert(END, '\n') self.w2.insert(END, shuchu2) root = Tk() root.geometry('500x300+100+200') root.title('我的第一个GUI程序') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
- Radiobutton单选框组件
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox import webbrowser class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): self.v=StringVar() #用来存放Button1和Button2的值 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())#返回的是value值 if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- Checkbutton多选框:
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox import webbrowser class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): self.codeHobby=IntVar() #接收codeHobby的值 self.videoHobby=IntVar() #接收videoHobby的值 self.c1=Checkbutton(self,text='敲代码',variable=self.codeHobby,onvalue=1,offvalue=0)#选中值为1 不选中值为0 self.c2=Checkbutton(self,text='看视频',variable=self.videoHobby, onvalue=1,offvalue=0)#选中值为1 不选中值为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('500x300+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- canvas画布:矩形区域,可以放置图形、图像、组件等
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox import webbrowser import random class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): self.canvas=Canvas(self,width=600,height=400,bg='green') self.canvas.pack() #画一条直线,(10,10)为起始点 (30,20)为中间点 (40,50)为终点 line=self.canvas.create_line(10,10,30,20,40,50) #画一个矩形 (50,50)为矩形左上角的坐标(100,100)为矩形右下角的坐标 rect=self.canvas.create_rectangle(50,50,100,100) #画一个椭圆,坐标两双。为椭圆的边界矩形左上角和底部右下角 oval=self.canvas.create_oval(50,50,100,100) global photo photo=PhotoImage(file='img1.gif') self.canvas.create_image(250,170,image=photo) Button(self,text='画10个矩形',command=self.draw50Rect).pack(side='left') def draw50Rect(self): #循环10次 for i in range(0,10): x1=random.randrange(int(self.canvas['width'])/2) #从0到canvas宽度一半的随机数 y1=random.randrange(int(self.canvas['height'])/2) #从0到canvas高度一半的随机数 x2=x1+random.randrange(int(self.canvas['width'])/2) y2=y1+random.randrange(int(self.canvas['height'])/2) self.canvas.create_rectangle(x1,x2,y1,y2) if __name__ =='__main__': root = Tk() root.geometry('500x300+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- 布局管理器:tkinter提供了三种管理器:pack、grid、place
pack要不垂直排列、要不水平排列
grid实现网格排列、组件放到单元格里面
place可以通过像素控制组件
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 |
# 测试一个经典的GUI程序的写法,使用面向对象的方式 from tkinter import * from tkinter import messagebox import webbrowser import random class Application(Frame): # 一个经典的GUI程序的类的写法 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('300x100+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- 通过grid布局-实现计算器软件界面
Python enumerate() 函数
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
代码:
# 计算机软件界面的设计 from tkinter import * from tkinter import messagebox import webbrowser import random class Application(Frame): # 一个经典的GUI程序的类的写法 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) #输入框跨四列 pady=10相当于Entry距离下面的组件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) # 列的索引值加1 else: Button(self,text=c,width=2).grid(row=rindex+1,column=cindex,sticky=NSEW) #贴左边和右边 上边和下边 即填满了单元格 if __name__ =='__main__': root = Tk() root.geometry('300x300+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- pack布局管理器:按照垂直或者水平自然排布,代码量最少,最简单
# 计算机软件界面的设计 from tkinter import * from tkinter import messagebox import webbrowser import random class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): #通过pack布局实现钢琴的界面 #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): Label(f2,width=5,height=10,borderwidth=1,relief='solid', bg='black' if i%2==0 else 'white').pack(side='left',padx=2) if __name__ =='__main__': root = Tk() root.geometry('700x220+100+200') root.title('Text多行文本框测试') app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
- 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’ | ‘n’、‘s’、‘w’、‘e’、‘nw’、‘sw’、‘se’、‘ne’、‘center’ |
代码:
# 计算机软件界面的设计 from tkinter import * from tkinter import messagebox import webbrowser import random class Application(Frame): # 一个经典的GUI程序的类的写法 def __init__(self,master=None): super().__init__(master) # super()代表的是父类的定义,而不是父类对象 self.master=master self.pack() self.createWidget() def createWidget(self): #通过pack布局实现钢琴的界面 #Frame是一个矩形区域,就是用来放置其他子组件 f1=Frame(root,width=200,height=200,bg='green') f1.place(x=30,y=30) #相对于窗口(30,30) Button(root,text='浙江理工').place(relx=0.2,x=100,y=20,relwidth=0.2,relheight=0.5) #relwidth=0.2,relheight=0.5表示相对于root来说宽乘上0.2 高乘上0.5 #x=100表示绝对位置x-100 但是又有relx=0。2 表示 先相对于root取0.2的位置 然后向右移100 变成了偏移量 Button(f1, text='电科').place(relx=0.6, rely=0.7) #左上角的位置 放在f1宽度0.6的位置 高度0.7的位置 Button(f1, text='厉俊').place(relx=0.5, rely=0.2) # 左上角的位置 放在f1宽度0.5的位置 高度0.2的位置 if __name__ =='__main__': root = Tk() root.geometry('700x330+100+200') root.title('布局管理place') root['bg']='white' app = Application(master=root) root.mainloop() # 调用组件的mainloop()方法,进入事件循环 # 产生一个空白窗口
效果图:
转载请注明出处,欢迎讨论和交流!