python---基础知识回顾(九)图形用户界面-------Tkinter
前戏:老牌python GUI程序(Tkinter)
- import tkinter.messagebox as messagebox
- class Application(Frame):
- def __init__(self,master=None):
- Frame.__init__(self,master,bg="red") #设置框架类的父类(基于master<主窗体>),frame可以是看做控件的父容器
- self.pack() #显示frame控件
- self.createWidgets()
- def createWidgets(self): #用于创建控件(是frame的子)
- self.nameInput = Entry(self)
- self.nameInput.pack()
- self.alertButton = Button(self,text="Hello",command=self.hello)
- self.alertButton.pack()
- def hello(self):
- name = self.nameInput.get()
- messagebox.showinfo("Message","Hello, %s"%name)
- root = Tk()
- root.title("标题")
- root.wm_minsize(,)
- app = Application(root)
- app.mainloop()
前置:各个参数了解:
- tkinter模块常用参数(python3)
- 、使用tkinter.Tk() 生成主窗口(root=tkinter.Tk());
- root.title(‘标题名’) 修改框体的名字,也可在创建时使用className参数来命名;
- root.resizable(,) 框体大小可调性,分别表示x,y方向的可变性;
- root.geometry(‘250x150’)指定主框体大小;
- root.quit() 退出;
- root.update_idletasks()
- root.update() 刷新页面;
- 、初级样例:
- import tkinter
- root=tkinter.Tk() #生成root主窗口
- label=tkinter.Label(root,text=’Hello,GUI’) #生成标签
- label.pack() #将标签添加到主窗口
- button1=tkinter.Button(root,text=’Button1’) #生成button1
- button1.pack(side=tkinter.LEFT) #将button1添加到root主窗口
- button2=tkinter.Button(root,text=’Button2’)
- button2.pack(side=tkinter.RIGHT)
- root.mainloop() #进入消息循环(必需组件)
- 、tkinter中的15种核心组件:
- Button 按钮;
- Canvas 绘图形组件,可以在其中绘制图形;
- Checkbutton 复选框;
- Entry 文本框(单行);
- Text 文本框(多行);
- Frame 框架,将几个组件组成一组
- Label 标签,可以显示文字或图片;
- Listbox 列表框;
- Menu 菜单;
- Menubutton 它的功能完全可以使用Menu替代;
- Message 与Label组件类似,但是可以根据自身大小将文本换行;
- Radiobutton 单选框;
- Scale 滑块;允许通过滑块来设置一数字值
- Scrollbar 滚动条;配合使用canvas, entry, listbox, and text窗口部件的标准滚动条;
- Toplevel 用来创建子窗口窗口组件。
- (在Tkinter中窗口部件类没有分级;所有的窗口部件类在树中都是兄弟。)
- 、组件的放置和排版(pack,grid,place)
- pack组件设置位置属性参数:
- after: 将组件置于其他组件之后;
- before: 将组件置于其他组件之前;
- anchor: 组件的对齐方式,顶对齐’n’,底对齐’s’,左’w’,右’e’
- side: 组件在主窗口的位置,可以为’top’,’bottom’,’left’,’right’(使用时tkinter.TOP,tkinter.E);
- fill 填充方式 (Y,垂直,X,水平)
- expand 1可扩展,0不可扩展
- grid组件使用行列的方法放置组件的位置,参数有:
- column: 组件所在的列起始位置;
- columnspam: 组件的列宽;
- row: 组件所在的行起始位置;
- rowspam: 组件的行宽;
- place组件可以直接使用坐标来放置组件,参数有:
- anchor: 组件对齐方式;
- x: 组件左上角的x坐标;
- y: 组件右上角的y坐标;
- relx: 组件相对于窗口的x坐标,应为0-1之间的小数;
- rely: 组件相对于窗口的y坐标,应为0-1之间的小数;
- width: 组件的宽度;
- heitht: 组件的高度;
- relwidth: 组件相对于窗口的宽度,-;
- relheight: 组件相对于窗口的高度,-;
- 、使用tkinter.Button时控制按钮的参数:
- anchor: 指定按钮上文本的位置;
- background(bg): 指定按钮的背景色;
- bitmap: 指定按钮上显示的位图;
- borderwidth(bd):指定按钮边框的宽度;
- command: 指定按钮消息的回调函数;
- cursor: 指定鼠标移动到按钮上的指针样式;
- font: 指定按钮上文本的字体;
- foreground(fg):指定按钮的前景色;
- height: 指定按钮的高度;
- image: 指定按钮上显示的图片;
- state: 指定按钮的状态(disabled);
- text: 指定按钮上显示的文本;
- width: 指定按钮的宽度
- padx 设置文本与按钮边框x的距离,还有pady;
- activeforeground按下时前景色
- textvariable 可变文本,与StringVar等配合着用
- 、文本框tkinter.Entry,tkinter.Text控制参数:
- background(bg) 文本框背景色;
- foreground(fg) 前景色;
- selectbackground选定文本背景色;
- selectforeground选定文本前景色;
- borderwidth(bd) 文本框边框宽度;
- font 字体;
- show 文本框显示的字符,若为*,表示文本框为密码框;
- state 状态;
- width 文本框宽度
- textvariable 可变文本,与StringVar等配合着用
- 、标签tkinter.Label组件控制参数:
- Anchor 标签中文本的位置;
- background(bg) 背景色;
- foreground(fg) 前景色;
- borderwidth(bd) 边框宽度;
- width 标签宽度;
- height 标签高度;
- bitmap 标签中的位图;
- font 字体;
- image 标签中的图片;
- justify 多行文本的对齐方式;
- text 标签中的文本,可以使用’\n’表示换行
- textvariable 显示文本自动更新,与StringVar等配合着用
- 、单选框和复选框Radiobutton,Checkbutton控制参数:
- anchor 文本位置;
- background(bg) 背景色;
- foreground(fg) 前景色;
- borderwidth 边框宽度;
- width 组件的宽度;
- height 组件高度;
- bitmap 组件中的位图;
- image 组件中的图片;
- font 字体;
- justify 组件中多行文本的对齐方式;
- text 指定组件的文本;
- value 指定组件被选中中关联变量的值;
- variable 指定组件所关联的变量;
- indicatoron 特殊控制参数,当为0时,组件会被绘制成按钮形式;
- textvariable 可变文本显示,与StringVar等配合着用
- 、组图组件Canvas控制参数:
- background(bg) 背景色;
- foreground(fg) 前景色;
- borderwidth 组件边框宽度;
- width 组件宽度;
- height 高度;
- bitmap 位图;
- image 图片;
- 绘图的方法主要以下几种:
- create_arc 圆弧;
- create_bitmap 绘制位图,支持XBM;
- create_image 绘制图片,支持GIF(x,y,image,anchor);
- create_line 绘制支线;
- create_oval; 绘制椭圆;
- create_polygon 绘制多边形(坐标依次罗列,不用加括号,还有参数,fill,outline);
- create_rectangle 绘制矩形((a,b,c,d),值为左上角和右下角的坐标);
- create_text 绘制文字(字体参数font,);
- create_window 绘制窗口;
- delete 删除绘制的图形;
- itemconfig 修改图形属性,第一个参数为图形的ID,后边为想修改的参数;
- move 移动图像(,,),1为图像对象,4为横移4像素,0为纵移像素,然后用root.update()刷新即可看到图像的移动,为了使多次移动变得可视,最好加上time.sleep()函数;
- 只要用create_方法画了一个图形,就会自动返回一个ID,创建一个图形时将它赋值给一个变量,需要ID时就可以使用这个变量名。
- coords(ID) 返回对象的位置的两个坐标(4个数字元组);
- 对于按钮组件、菜单组件等可以在创建组件时通过command参数指定其事件处理函数。方法为bind;或者用bind_class方法进行类绑定,bind_all方法将所有组件事件绑定到事件响应函数上。
- 、菜单Menu
- 参数:
- tearoff 分窗,0为在原窗,1为点击分为两个窗口
- bg,fg 背景,前景
- borderwidth 边框宽度
- font 字体
- activebackgound 点击时背景,同样有activeforeground,activeborderwidth,disabledforeground
- cursor
- postcommand
- selectcolor 选中时背景
- takefocus
- title
- type
- relief
- 方法:
- menu.add_cascade 添加子选项
- menu.add_command 添加命令(label参数为显示内容)
- menu.add_separator 添加分隔线
- menu.add_checkbutton添加确认按钮
- delete 删除
- 、事件关联
- bind(sequence,func,add)——
- bind_class(className,sequence,func,add)
- bind_all(sequence,func,add)
- 事件参数:
- sequence 所绑定的事件;
- func 所绑定的事件处理函数;
- add 可选参数,为空字符或‘+’;
- className 所绑定的类;
- 鼠标键盘事件
- 鼠标左键按下,2表示中键,3表示右键;
- 同上;
- 鼠标左键释放;
- 按住鼠标左键移动;
- 双击左键;
- 鼠标指针进入某一组件区域;
- 鼠标指针离开某一组件区域;
- 滚动滚轮;
- 按下A键,A可用其他键替代;
- 同时按下alt和A;alt可用ctrl和shift替代;
- 快速按两下A;
- 大写状态下按A;
- 窗口事件
- Activate 当组件由不可用转为可用时触发;
- Configure 当组件大小改变时触发;
- Deactivate 当组件由可用转变为不可用时触发;
- Destroy 当组件被销毁时触发;
- Expose 当组件从被遮挡状态中暴露出来时触发;
- Unmap 当组件由显示状态变为隐藏状态时触发;
- Map 当组件由隐藏状态变为显示状态时触发;
- FocusIn 当组件获得焦点时触发;
- FocusOut 当组件失去焦点时触发;
- Property 当窗体的属性被删除或改变时触发;
- Visibility 当组件变为可视状态时触发;
- 响应事件
- event对象(def function(event)):
- char 按键字符,仅对键盘事件有效;
- keycode 按键名,仅对键盘事件有效;
- keysym 按键编码,仅对键盘事件有效;
- num 鼠标按键,仅对鼠标事件有效;
- type 所触发的事件类型;
- widget 引起事件的组件;
- width,heigh组件改变后的大小,仅Configure有效;
- x,y 鼠标当前位置,相对于窗口;
- x_root,y_root 鼠标当前位置,相对于整个屏幕
- 、弹窗
- messagebox._show函数的控制参数:
- default 指定消息框按钮;
- icon 指定消息框图标;
- message 指定消息框所显示的消息;
- parent 指定消息框的父组件;
- title 标题;
- type 类型;
- simpledialog模块参数:
- title 指定对话框的标题;
- prompt 显示的文字;
- initialvalue 指定输入框的初始值;
- filedialog 模块参数:
- filetype 指定文件类型;
- initialdir 指定默认目录;
- initialfile 指定默认文件;
- title 指定对话框标题
- colorchooser模块参数:
- initialcolor 指定初始化颜色;
- title 指定对话框标题;
- 、字体(font)
- 一般格式:
- (’Times - bold’)
- (‘Times’,,’bold’,’italic’) 依次表示字体、字号、加粗、倾斜
- 补充:
- config 重新配置
- label.config(font=’Arial -%d bold’ % scale.get())
- 依次为字体,大小(大小可为字号大小),加粗
- tkinter.StringVar 能自动刷新的字符串变量,可用set和get方法进行传值和取值,类似的还有IntVar,DoubleVar…
常用参数
label:
- def callback():
- var.set("hhhhhhh")
- root = Tk()
- var = StringVar()
- var.set("")
- frame1 = Frame(root)
- frame2 = Frame(root)
- lb = Label(frame1,textvariable=var,padx=)
- lb.pack(side=LEFT)
- # img = Image(file="1.gif",imgtype="photo")
- img = PhotoImage(file="1.gif")
- lb2 = Label(frame1,image=img)
- lb2.pack(side=RIGHT)
- btnCm = Button(frame2,text="下一步",command=callback)
- btnCm.pack()
- frame1.pack()
- frame2.pack()
- root.mainloop()
label标签的使用(使用图片)
Checkbutton:
- from tkinter import *
- root =Tk()
- v = IntVar() #选中为1,未选中为0
- c = Checkbutton(root,text="Test",variable=v)
- c.pack()
- l = Label(root,textvariable=v)
- l.pack()
- root.mainloop()
Checkbutton使用(1)
- from tkinter import *
- root =Tk()
- GIRLS = ["asd",'dsa','fef','fwaf']
- v = []
- def change():
- for i in v:
- print(i.get())
- for girl in GIRLS:
- v.append(IntVar())
- b = Checkbutton(root,text=girl,variable=v[-],command=change) #使用一个固有变量来记录状态
- b.pack(anchor=W) #控件相对主窗口在左边
- root.mainloop()
Checkbutton的使用(2)
Radiobutton:
- #对于单选框,多个按钮只对应一个变量,复选框,多个按钮对应多个值
- from tkinter import *
- def change():
- print(v.get())
- root = Tk()
- v = IntVar()
- Radiobutton(root,text="one",variable=v,value=,command=change).pack(anchor=W)
- Radiobutton(root,text="two",variable=v,value=,command=change).pack(anchor=W)
- Radiobutton(root,text="three",variable=v,value=,command=change).pack(anchor=W)
- root.mainloop()
Radiobutton的使用(1)
- from tkinter import *
- def change():
- print(v.get())
- root = Tk()
- v = IntVar()
- Langes = [
- ("python",),
- ("javascript",),
- ("Lua",),
- ("Ruby",)
- ]
- group = LabelFrame(root,text="选择喜欢的语言",padx=5,pady=5)
group.pack(padx=10,pady=10)
- for key,val in Langes:
- Radiobutton(group,text=key,variable=v,value=val,command=change).pack(anchor=W)
- root.mainloop()
Radiobutton的使用(2)
- #对于单选框,多个按钮只对应一个变量,对于复选框,多个按钮对应多个值(使用列表获取)
- 注意:
- root = Tk()
- v = IntVar()
- 这里我们声明的变量全部应该写在主窗口生成后,才可以
- 不然当我们将变量写在主窗口生成前
- v = IntVar()
- root = Tk()
- 会报错
- AttributeError: 'NoneType' object has no attribute '_root'
- .首先进入IntVar类
- class IntVar(Variable):
- def __init__(self, master=None, value=None, name=None):
- Variable.__init__(self, master, value, name)
- .进入父类
- class Variable:
- def __init__(self, master=None, value=None, name=None):
- ...
- if not master: #看此处(master是主窗口,是传参,但是我们使用的时候并没有传入,所以为空,进入下面代码)
- master = _default_root #_default_root是什么
- self._root = master._root()
- self._tk = master.tk
- ...
- ._default_root查找
- _support_default_root = #也有用,后面看
- _default_root = None #是一个全局变量,代表主窗口
- 但是他也为空,所以出现了上面的属性错误,None没有_root()方法
- ------------------------------------------------------------------
- 开始查看Tk()
- root = Tk()
- .查看源码
- class Tk(Misc, Wm):
- def __init__(self, screenName=None, baseName=None, className='Tk',
- useTk=, sync=, use=None):
- ...
- if useTk: #这里默认传入1,进入下面逻辑
- self._loadtk()
- ...
- .查看self._loadtk()方法
- def _loadtk(self):
- self._tkloaded =
- global _default_root
- # Version sanity checks
- ......
- # Create and register the tkerror and exit commands
- # We need to inline parts of _register here, _ register
- # would register differently-named commands.
- ......
- if _support_default_root and not _default_root: #查看上面的全局变量,发现可以进入下面的逻辑代码中
- _default_root = self #所以_default_root就是主窗口
- ......
- ------------------------------------------------------------------
- 结论:由上面发现可以知道:
- IntVar等变量的使用需要_default_root(当我们没有传入master时),而主窗口生成root=Tk()时,内部代码将_default_root实现了。所以两者顺序需要保证先后
原因:源码分析
Entry:
- from tkinter import *
- root = Tk()
- input = Entry(root)
- input.pack(padx=,pady=)
- input.delete(, END) #先清空按照索引
- input.insert(,"请输入内容...")
- root.mainloop()
Entry的使用(1)
- from tkinter import *
- root = Tk()
- Lb1 = Label(root,text="作品:").grid(row=,column=)
- Lb1 = Label(root,text="作者:").grid(row=,column=)
- Ip1 = Entry(root)
- Ip1.grid(row=,column=,padx=,pady=)
- Ip2 = Entry(root)
- Ip2.grid(row=,column=,padx=,pady=)
- def show():
- print("作品:《%s》"%Ip1.get())
- print("作者:%s"%Ip2.get())
- Button(root,text="获取数据",command=show).grid(row=,column=,sticky=W,padx=,pady=)
- Button(root,text="退出",command=root.quit).grid(row=,column=,sticky=E,padx=,pady=)
- root.mainloop()
Entry的使用(2)
- from tkinter import *
- root = Tk()
- Lb1 = Label(root,text="账号:").grid(row=,column=)
- Lb1 = Label(root,text="密码:").grid(row=,column=)
- v1 = StringVar()
- v2 = StringVar()
- Ip1 = Entry(root)
- Ip1.grid(row=,column=,padx=,pady=)
- Ip2 = Entry(root,show="*")
- Ip2.grid(row=,column=,padx=,pady=)
- def show():
- print("账号:%s"%Ip1.get())
- print("密码:%s"%Ip2.get())
- Button(root,text="获取数据",command=show).grid(row=,column=,sticky=W,padx=,pady=)
- Button(root,text="退出",command=root.quit).grid(row=,column=,sticky=E,padx=,pady=)
- root.mainloop()
Entry的使用(密码设置)
- from tkinter import *
- root = Tk()
- Lb1 = Label(root,text="账号:").grid(row=,column=)
- Lb1 = Label(root,text="密码:").grid(row=,column=)
- def test():
- if Ip1.get() == "root":
- print("正确")
- return True
- else:
- print("错误")
- Ip1.delete(,END)
- return False
- Ip1 = Entry(root,validate="focusout",validatecommand=test)
- Ip1.grid(row=,column=,padx=,pady=)
- Ip2 = Entry(root,show="*")
- Ip2.grid(row=,column=,padx=,pady=)
- root.mainloop()
Entry的使用(事件处理<焦点>和数据验证validatecommand)
- #注意:只有当validatecommand验证失败,才会去触发invalidcommand事件.是为了避免函数过长,而且是代码简便
- from tkinter import *
- root = Tk()
- Lb1 = Label(root,text="账号:").grid(row=,column=)
- Lb1 = Label(root,text="密码:").grid(row=,column=)
- def test():
- if Ip1.get() == "root":
- print("正确")
- return True
- else:
- print("错误")
- Ip1.delete(,END)
- return False
- def test2():
- print("数据验证失败,我被调用...")
- Ip1 = Entry(root,validate="focusout",validatecommand=test,invalidcommand=test2)
- Ip1.grid(row=,column=,padx=,pady=)
- Ip2 = Entry(root,show="*")
- Ip2.grid(row=,column=,padx=,pady=)
- root.mainloop()
Entry的使用(invalidcommand)
- 对于Entry中的get方法获取数据和textvariable参数中的StringVar类型数据的使用区别:
- ---------------------------------------------------------------------
- v1 = StringVar()
- Ip1 = Entry(root,textvariable=v1,validate="focusout",validatecommand=test,invalidcommand=test2)
- Ip1.get()
- v1.get()
- ---------------------------------------------------------------------
- 控件的get方法能够获取任何时候的输入框中的数据。
- 而textvariable中的值,当存在validate验证时,只有当验证通过后才会被赋值给变量textvariable。
补充:输入框的事件:
- focus: 获得或失去时都调用
- focusin: 获得焦点时调用
- focusout: 失去焦点时
- key: 当输入框被编辑时,(有按键输入)
- none: 不会开启验证(默认),注意是字符none,不是None
补充:上面的验证函数都是没有参数的,随意添加参会报错
- TypeError: test2() missing required positional argument: '..'
那么如何传入参数?Tkinter为验证函数提供了一些参数
参数 | 含义 |
%d | 操作(触发事件)代码:0表示删除时触发,1插入时,2获得,失去焦点或textvariable值被修改 |
%i |
1.当用户尝试插入或删除操作的时候,该选项表示插入或删除的位置(索引号) 2.如果是由于获得,失去焦点或者textvariable值被修改,而调用验证函数,该值是-1 |
%P |
1.当输入框的值允许改变的时候,该值有效 2.该值为输入框的最新文本 |
%s | 该值为调用验证函数前输入框的文本内容 |
%S |
1.当插入或删除操作触发验证函数的时候,该值有效 2.该选项仅仅表示被插入或删除的值 |
%v | 该组件当前的validate选项的值(触发条件) |
%V |
1.调用验证函数的原因(触发条件) 2.focusin,focusout,key,forced(textvariable值被修改) |
%W | 该组件的名称(该控件的id) |
- from tkinter import *
- root = Tk()
- Lb1 = Label(root,text="账号:").grid(row=,column=)
- Lb1 = Label(root,text="密码:").grid(row=,column=)
- def test():
- if Ip1.get() == "root":
- print("正确")
- return True
- else:
- print("错误")
- Ip1.delete(,END)
- return False
- def test2(p_con,s_con,v_func,v_res,w_name):
- print(p_con,s_con,v_func,v_res,w_name) #waff waff focusout focusout .(和下面的id(Ip1)一致)
- return True
- v1 = StringVar()
- v2 = StringVar()
- #注意使用前需要先进行注册
- testCMD = root.register(test2)
- Ip1 = Entry(root,textvariable=v1,validate="focusout",validatecommand=(testCMD,"%P","%s","%v","%V","%W"))
- print(id(Ip1)) #
- Ip1.grid(row=,column=,padx=,pady=)
- Ip2 = Entry(root,show="*")
- Ip2.grid(row=,column=,padx=,pady=)
- root.mainloop()
额外参数测试
当然上面的只是提供的特殊参数,我们可以传入自己想要传递的数据,不过,这些自定义函数都是需要我们进行注册。
- def test(a,b):
- print(a,b)
- if Ip1.get() == "root":
- print("正确")
- return True
- else:
- print("错误")
- Ip1.delete(,END)
- return False
- testCMD2 = root.register(test)
- he = "hhhhh"
- ll = "gun"
- Ip1 = Entry(root,textvariable=v1,validate="focusout",validatecommand=(testCMD2,he,ll))
- ------------------------------------------------------------------
- hhhhh gun
- 正确
自定义参数传递
- from tkinter import *
- root = Tk()
- v1 = StringVar()
- v2 = StringVar()
- v3 = StringVar()
- def test(content):
- if content.isdigit():
- return True
- else:
- return False
- def calc():
- res = int(v1.get())+int(v2.get())
- v3.set(res)
- testCMD = root.register(test)
- e1 = Entry(root,textvariable=v1,validate="key",validatecommand=(testCMD,"%P")).grid(row=,column=)
- Lb1 = Label(root,text="+").grid(row=,column=)
- e2 = Entry(root,textvariable=v2,validate="key",validatecommand=(testCMD,"%P")).grid(row=,column=)
- Label = Label(root,text="=").grid(row=,column=)
- e3 = Entry(root,textvariable=v3,state="readonly").grid(row=,column=)
- Button(root,text="求和",command=calc).grid(row=,column=)
- root.mainloop()
Entry案例(求和操作)
补充:布局的pack和grid,和place区别
- 我们使用 pack 函数的时候,默认先使用的放到上面,然 后 依次向下排,它会给我们的组件一个自认为合适的位置 和大小,这是默认方式。
- 无严格界限要求。(简单布局推荐)
- grid是严格按照表格的行列进行划分区域的,需要我们提前进行设计,灵活程度低于pack,但是对于我们理解更加容易(学习推荐)
- place:允许用户指定组件的大小和位置(不推荐,但是在某些情况有妙用)
- 注意:pack和grid不要混用,不然无法进行
- from tkinter import *
- master = Tk()
- photo = PhotoImage(file="1.gif")
- Lable(master,image=photo).pack() #会被button覆盖
- def click():
- print("center")
- Button(master,text="create",command=click).place(relx=0.5,rely=0.5,anchor=CENTER) #relx和rely是设置在窗口的位置在中间,anchor是设置这个控件相对于窗口中间的位置
- master.mainloop()
place设置居中
- from tkinter import *
- master = Tk()
- Label(master,bg="red").place(relx=0.5,rely=0.5,relheight=0.75,relwidth=0.75,anchor=CENTER)
- Label(master,bg="green").place(relx=0.5,rely=0.5,relheight=0.5,relwidth=0.5,anchor=CENTER)
- Label(master,bg="blue").place(relx=0.5,rely=0.5,relheight=0.25,relwidth=0.25,anchor=CENTER)
- master.mainloop()
place的部分参数
继续说说pack中的参数:
- side:按扭停靠在窗口的哪个位置
- left: 左
- top: 上
- right: 右
- botton: 下
- fill:填充
- x:水平方向填充
- y:竖直方向填充
- both:水平和竖直方向填充
- none:不填充
- expand:
- yes:扩展整个空白区
- no:不扩展
- anchor:
- N:北 下
- E:东 右
- S:南 下
- W:西 左
- CENTER:中间
- padx:x方向的外边距
- pady:y方向的外边距
- ipadx:x方向的内边距
- ipady:y方向的内边距
pack中的参数
代码测试:
- from tkinter import *
- root = Tk()
- Button(root,text='A').pack(side=LEFT,expand=NO,fill=Y)
- Button(root,text='B').pack(side=TOP,expand=NO,fill=BOTH)
- Button(root,text='C').pack(side=RIGHT,expand=NO,fill=NONE)
- Button(root,text='D').pack(side=LEFT,expand=NO,fill=Y)
- Button(root,text='E').pack(side=TOP,expand=NO,fill=BOTH)
- Button(root,text='F').pack(side=BOTTOM,expand=NO)
- Button(root,text='G').pack(anchor=SE)
- root.mainloop()
注意:expand,当你拉动窗口时(放大),所有你设置为允许扩充的控件都会去改变形状扩展空白区域(注意,我们设置的fill填充参数,当我们改变窗口大小时,也会随着设置的方向进行改变<前提是布局未被限制>)
- Button(root,text='A').pack(side=LEFT,expand=YES,fill=Y)
expand:占据空白区域
fill:会填充设置的方向Y
至于grid就不再多说
Listbox:
- from tkinter import *
- master = Tk()
- Lb = Listbox(master)#设置多选selectmode=EXTENDED
- Lb.pack()
- for item in ["福娃","f非","各方",'端口']:
- Lb.insert(END,item) #插入方向,从后方...(是按照索引来的)
- Btn = Button(master,text="删除当前选中",command=lambda x=Lb:x.delete(ACTIVE))
- Btn.pack()
- master.mainloop()
Listbox的使用(默认单选,可以设置多选)
- from tkinter import *
- master = Tk()
- Lb = Listbox(master,selectmode=EXTENDED,)
- Lb.pack()
- for item in range():
- Lb.insert(END,item) #插入方向,从后方...(是按照索引来的)
- def del_lb():
- ls = list(Lb.curselection())
- ls.reverse() #需要先翻转过来,在从后向前删除(不然删除会导致索引不及时,删错元素)
- for index in ls:
- Lb.delete(index)
- Btn = Button(master,text="删除当前选中",command=del_lb)
- Btn.pack()
- master.mainloop()
Listbox的使用(多选删除)
- from tkinter import *
- master = Tk()
- #:生成滚动条
- sb = Scrollbar(master)
- sb.pack(side=RIGHT,fill=Y)
- #:生成ListBox,将其与滚动条相关联,yscrollcommand (单向关联<Listbox去改变ScrollBar>:鼠标滚轮滚动内容,滚动条会滑动,但是滚动条变化时,内容不会变化)
- Lb = Listbox(master,selectmode=EXTENDED,height=,yscrollcommand=sb.set) #默认显示10条,我们可以设置滚轮或者height行数
- Lb.pack()
- #:将滚动条滚动事件与ListBox的视图显示相关联 (单向关联<ScrollBar去改变Listbox>:滚动条变化时,内容会变化)
- sb.config(command=Lb.yview)
- #注意:2和3相关联会获得我们想要的结果
- for item in range():
- Lb.insert(END,item) #插入方向,从后方...(是按照索引来的)
- master.mainloop()
Listbox的使用(ScrollBar的使用)(ScrollBar和Listbox相互关联:ScrollBar中config和Listbox中的yscrollcommand)
Scale:
- from tkinter import *
- master = Tk()
- s1 = Scale(master,from_ =, to =) #默认是垂直的
- s1.pack()
- s2 = Scale(master,from_=,to=,orient=HORIZONTAL) #设置为水平
- s2.pack()
- Button(master,text="获取数值",command=lambda :print(s1.get(),s2.get())).pack()
- master.mainloop()
Scale的使用(相对于ScrollBar可以设置滚动范围<默认垂直,使用orient修改水平>)
- from tkinter import *
- master = Tk()
- s1 = Scale(master,from_ =, to =,tickinterval=) #tickinterval是设置分为几份
- s1.pack()
- s2 = Scale(master,from_=,to=,orient=HORIZONTAL,resolution=) #resolution设置每次移动的固定步长
- s2.pack()
- Button(master,text="获取数值",command=lambda :print(s1.get(),s2.get())).pack()
- master.mainloop()
Scale的固定步长resolution和均分数量tickinterval(将范围分为几份,并且显示刻度)
Text:功能多(方法多)
- from tkinter import *
- master = Tk()
- text = Text(master,width=,height=)
- text.pack()
- # Special tags, marks and insert positions
- # SEL='sel' #选择的文字被替换
- # SEL_FIRST='sel.first' #选中的文字的前面插入
- # SEL_LAST='sel.last' #选中的文字后面被插入
- # END='end' #在当前文档结尾插入
- # INSERT='insert' #在当前光标位置插入
- # CURRENT='current' #在当前位置插入
- # ANCHOR='anchor'
- # ALL='all' # e.g. Canvas.delete(ALL)
- # def insert(self, index, chars, *args):
- # """Insert CHARS before the characters at INDEX. An additional
- # tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
- # self.tk.call((self._w, 'insert', index, chars) + args)
- text.insert(INSERT,"")
- text.insert(END,"")
- text.insert(CURRENT,"")
- text.insert(INSERT,"")
- master.mainloop()
Text的使用(功能多样,甚至可以显示图片,链接,html和网页浏览)
- from tkinter import *
- master = Tk()
- text = Text(master,width=,height=)
- text.pack()
- # Special tags, marks and insert positions
- # SEL='sel' #选择的文字被替换
- # SEL_FIRST='sel.first' #选中的文字的前面插入
- # SEL_LAST='sel.last' #选中的文字后面被插入
- # END='end' #在当前文档结尾插入
- # INSERT='insert' #在当前光标位置插入
- # CURRENT='current' #在当前位置插入
- # ANCHOR='anchor'
- # ALL='all' # e.g. Canvas.delete(ALL)
- # def insert(self, index, chars, *args):
- # """Insert CHARS before the characters at INDEX. An additional
- # tag can be given in ARGS. Additional CHARS and tags can follow in ARGS."""
- # self.tk.call((self._w, 'insert', index, chars) + args)
- text.insert(INSERT,"")
- text.insert(END,"")
- photo = PhotoImage(file="1.gif") #注意photo对象写在函数体外,若在函数体中,生存周期一到,就会被释放。无法显示。,解释如下面所述
- def show(): #此时是事件button点击,进入处理,处理后,才会进入IO循环中去显示数据,若是数据在函数体中被回收,那么久无法显示出来
- a = "adsafafw" #字符串是被存放在常量区,不会被删除的,所以两个的id是一致的
- text.image_create(INSERT,image=photo)
- text.insert(END,a)
- print(id(a)) #
- def test():
- b = "adsafafw"
- print(id(b)) # 和上面的数据a都是在函数体中,id一致。是使用的一个数据(存放在常量区)
- test()
- btn = Button(text,text="试试看",command=show)
- text.window_create(INSERT,window=btn) #要想显示控件,需要将text设置为窗口("""Create a window at INDEX.""")
- master.mainloop()
Text的使用(插入图片和控件)(强行回顾一次函数体中数据的生存周期)
- from tkinter import *
- master = Tk()
- text = Text(master,width=,height=)
- text.pack()
- text.insert(CURRENT,"adfwgthjdjxc")
- #注意行数是从1开始,列数是从0开始,索引写法可以使用小数点连接:1.2---第一行第3列 特殊:行.end(该行最后的索引),特殊的需要使用引号
- txt = text.get(1.2,'1.end') #"""Return the text from INDEX1 to INDEX2 (not included)."""
- txt2 = text.get(1.1,1.6)
- print(txt,txt2) #fwgthjdjxc dfwgt
- master.mainloop()
Text的使用(索引行列)
- from tkinter import *
- master = Tk()
- text = Text(master,width=,height=)
- text.pack()
- text.insert(CURRENT,"fgweagawgrhssdf")
- #Marks标记
- #.简单使用:
- text.mark_set("bj","1.3") #在1.3处设置标记,名为bj,就像书签一样,方便操作。注意mark_set和mark_unset对应
- #默认标记是记住右边的那个字符(第一次设置后就跟定他了)e字符
- text.insert("bj","") #fgw66eagawgrhssdf 向e字符左端插入
- text.insert("bj",'') #fgw6688eagawgrhssdf 还是向e字符左端插入
- text.mark_unset("bj")
- text.delete(1.0,END) #清空数据
- #.标志被删除了之后的反应:
- text.insert(CURRENT,"fgweagawgrhssdf")
- text.mark_set("bj","1.3") #在1.3处设置标记,名为bj,就像书签一样,方便操作。注意mark_set和mark_unset对应
- text.delete(1.2,1.5) #注意当标记位置被删除了的话,会自动寻找到删除的字符串的下一个字符,以他为标志
- #删除字符串后面的那个紧接的字符是g,以他为标志
- text.insert("bj","") #fg66gawgrhssdf 向g字符左端插入
- text.insert("bj",'') #fg6688gawgrhssdf 还是向g字符左端插入
- text.mark_unset("bj")
- text.delete(1.0,END)
- #.前面都是以标志位为基准,放在右边。修改将标志位放在左边:mark_gravity
- text.insert(CURRENT,"fgweagawgrhssdf")
- text.mark_set("bj","1.3") #在1.3处设置标记,名为bj,就像书签一样,方便操作。注意mark_set和mark_unset对应
- text.mark_gravity("bj",LEFT)
- #默认标记是记住右边的那个字符(第一次设置后就跟定他了)e字符
- text.insert("bj","") #fgw66eagawgrhssdf 向e字符左端插入
- text.insert("bj",'') #fgw6688eagawgrhssdf 还是向e字符左端插入
- text.mark_unset("bj")
- master.mainloop()
Text的使用(Marks标记)
- from tkinter import *
- master = Tk()
- text = Text(master,width=,height=)
- text.pack()
- text.insert(CURRENT,"gag g efwa h eshhe fawf")
- text.tag_add("tag1","1.7","1.12","1.16") #索引双数为范围,单数为一个字符
- text.tag_config("tag1",background="yellow",foreground="white") #config是设置样式 foreground是前景色,字体颜色
- #新样式覆盖旧样式
- text.tag_add("tag2","1.9","1.12") #索引双数为范围,单数为一个字符
- text.tag_config("tag2",background="blue",foreground="white") #config是设置样式 foreground是前景色,字体颜色
- #设置tag的优先级:作用就是较低的优先级样式是无法覆盖高优先级的
- text.tag_lower("tag2") #降低
- # text.tag_raise("tag1") #提高
- master.mainloop()
Text的使用(tag使用:可以对内容进行样式修改)
- from tkinter import *
- import webbrowser
- master = Tk()
- text = Text(master,width=,height=,selectbackground="green")
- text.pack()
- text.insert(CURRENT,"gag g efwa h eshhe fawf")
- text.tag_add("a","1.7","1.12","1.16") #索引双数为范围,单数为一个字符
- text.tag_config("a",background="yellow",foreground="red",underline=True,font="") #config是设置样式 foreground是前景色,字体颜色
- def show_arrow_cursor(*args):
- text.config(cursor="arrow") #箭头
- def show_xterm_cursor(*args):
- text.config(cursor="xterm") #光标线
- def click(*args):
- webbrowser.open("http://www.baidu.com")
- text.tag_bind("a","<Enter>",show_arrow_cursor) #<Enter>是鼠标进入的样式
- text.tag_bind("a","<Leave>",show_xterm_cursor) #鼠标离开
- text.tag_bind("a","<Button-1>",click) #单击样式
- # def tag_bind(self, tagName, sequence, func, add=None):
- master.mainloop()
- SEQUENCE is a string of concatenated event
- patterns. An event pattern is of the form
- <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
- of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
- Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
- B3, Alt, Button4, B4, Double, Button5, B5 Triple,
- Mod1, M1. TYPE is one of Activate, Enter, Map,
- ButtonPress, Button, Expose, Motion, ButtonRelease
- FocusIn, MouseWheel, Circulate, FocusOut, Property,
- Colormap, Gravity Reparent, Configure, KeyPress, Key,
- Unmap, Deactivate, KeyRelease Visibility, Destroy,
- Leave and DETAIL is the button number for ButtonPress,
- ButtonRelease and DETAIL is the Keysym for KeyPress and
- KeyRelease. Examples are
- <Control-Button-> for pressing Control and mouse button or
- <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
- An event pattern can also be a virtual event of the form
- <<AString>> where AString can be arbitrary. This
- event can be generated by event_generate.
- If events are concatenated they must appear shortly
- after each other.
- FUNC will be called if the event sequence occurs with an
- instance of Event as argument. If the return value of FUNC is
- "break" no further bound function is invoked.
- An additional boolean parameter ADD specifies whether FUNC will
- be called additionally to the other bound function or whether
- it will replace the previous function.
- Bind will return an identifier to allow deletion of the bound function with
- unbind without memory leak.
- If FUNC or SEQUENCE is omitted the bound function or list
- of bound events are returned."""
Text的使用(tag的使用:对其绑定事件)
- from tkinter import *
- import hashlib
- master = Tk()
- text = Text(master,width=,height=,selectbackground="green")
- text.pack()
- text.insert(INSERT,"gag g efwa h eshhe fawf")
- contents = text.get(1.0,END)
- def getData(contents):
- data = hashlib.md5(contents.encode())
- return data.hexdigest()
- cont = getData(contents)
- def check():
- data = getData(text.get(1.0,END))
- if data != cont:
- print("内容不一致")
- else:
- print("检测通过")
- Button(master,text="检测",command=check).pack()
- master.mainloop()
Text的使用(使用hashlib进行文本比较)
补充:使用hashlib进行文本(文件)比较
1.对于本地文件的比较:倾向于直接读取文件进行比较,毕竟hash计算也是需要读取文件内容,然后进行计算,对于两个文件,都要读取完毕,然后进行md5再进行比较。可能消耗会大于直接读取文件进行比较
2.对于网络传输文件,我们为了节省流量,最后在本地进行hash,向md5最后只需要在网络上传输32位数据即可。
推文:https://www.v2ex.com/t/257552
- from tkinter import *
- import hashlib
- root = Tk()
- text = Text(root,width=,height=)
- text.pack()
- text.insert(INSERT,"fea g ag awgwag\r\n")
- text.insert(INSERT,"ffge g agge awgag")
- def getIndex(text,index): #因为这个索引是一个小数 n.m n行m列,所以我们需要进一步处理
- print(text,index)
- return tuple(map(int,str.split(text.index(index),'.')))
- #map(func,iter) 这里func-->int() iter--->[n,m]可迭代
- start = '1.0'
- while True:
- pos = text.search('g',start,stopindex=END)
- if not pos:
- break
- print("找到位置是:",getIndex(text,pos))
- start = pos + "+1c"
- mainloop()
Text的使用(内容查找search方法,以及map回顾)
- from tkinter import *
- import hashlib
- master = Tk()
- text = Text(master,width=,height=,undo=True)
- text.pack()
- text.insert(INSERT,"gag g efwa h eshhe fawf")
- def undo():
- text.edit_undo()
- Button(master,text="撤销",command=undo).pack()
- master.mainloop()
Text的使用(edit_undo进行撤销操作)(开启undo后,每一次完整的操作,都会去入栈一次,撤销就是依次出栈)
- 默认会在每一次完整的操作后面加上一个“分隔符”入栈。那么什么是一次完整的操作:
- 是指每次焦点切换(鼠标移动点击改变光标位置,后进行操作),用户按下Enter,删除\插入操作的转换等之前的操作算是一次完整的操作(对于连续相同的操作,也只能算作一次完整的操作)
- from tkinter import *
- import hashlib
- master = Tk()
- text = Text(master,width=,height=,undo=True,autoseparators=False)
- text.pack()
- text.insert(INSERT,"gag g efwa h eshhe fawf")
- def cusSep(*args): #每次调用该函数,就还在该位置插入一个分隔符
- text.edit_separator()
- text.bind('<Key>',cusSep)
- def undo():
- text.edit_undo()
- Button(master,text="撤销",command=undo).pack()
- master.mainloop()
Text的使用(自定义分隔符插入位置edit_separator)
Canvas:(绘图使用)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=) #创建绘图区域,默认在主窗口居中
- w.pack()
- line1 = w.create_line(,,,,fill="yellow")
- line2 = w.create_line(,,,,fill="red",dash=(,)) #dash中元组第一个代表点划线长,第二个代表间隔长度
- rect1 = w.create_rectangle(,,,,fill="blue")
- w.coords(line1,,,,) #坐标移动,至少4个参数,基本上就是重新绘制这条线
- w.delete(line2) #删除这条线
- w.itemconfig(rect1,fill="red") #对某一个创建的图形项目进行配置属性
- w.itemconfig(line1,fill="green")
- Button(master,text="删除所有",command=lambda x=ALL:w.delete(x)).pack()
- master.mainloop()
Canvas的使用(直线和矩形绘制和修改配置,已经删除操作)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- w.create_line(,,,,fill="green",width=) #width是线宽
- w.create_line(,,,,fill="green",width=)
- w.create_rectangle(,,,,fill="green")
- w.create_rectangle(,,,,fill="yellow")
- #填充文字
- w.create_text(,,text="fwfwaf")
- master.mainloop()
Canvas的使用(create_text填写文字)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- w.create_rectangle(,,,,fill="green",dash=(,))
- w.create_oval(,,,,fill="pink") #创建椭圆
- w.create_arc(,,,,fill="blue",width=) #创建扇形需两个点,作为两个端点
- w.create_polygon(,,,,,,,,fill="white") #绘制多边形,会自动封闭图形(首尾)
- master.mainloop()
Canvas的使用(绘制椭圆和多边形,扇形)
- from tkinter import *
- import math
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- center_x =
- center_y =
- r =
- points = [
- #左上点
- center_x - int(r*math.sin(*math.pi/)),
- center_y - int(r*math.cos(*math.pi/)),
- #右上点
- center_x + int(r*math.sin(*math.pi/)),
- center_y - int(r*math.cos(*math.pi/)),
- #左下角
- center_x - int(r*math.sin(math.pi/)),
- center_y + int(r*math.cos(math.pi/)),
- #顶点
- center_x,
- center_y - r,
- #右下角
- center_x + int(r*math.sin(math.pi/)),
- center_y + int(r*math.cos(math.pi/)),
- ]
- print(points)
- w.create_polygon(points,fill="green",outline="black") #轮廓线
- master.mainloop()
Canvas的使用(五角星绘制:数学math模块回顾)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- def paint(event): #事件触发
- x1, y1 = (event.x-,event.y-)
- x2, y2 = (event.x+,event.y+)
- w.create_oval(x1,y1,x2,y2)
- w.bind("<B1-Motion>",paint) #鼠标左键点击移动
- master.mainloop()
Canvas的使用(事件绑定)
- from tkinter import *
- root = Tk()
- # 创建一个Canvas,设置其背景色为白色
- cv = Canvas(root,bg = 'white')
- d = {:'error',:'info',:'question',:'hourglass'}
- for i in d:
- cv.create_bitmap((*i,*i),bitmap = d[i])
- cv.pack()
- root.mainloop()
- # 使用bitmap属性来指定位图的名称,这个函数的第一个参数为一个点(x,y)指定位图存放位置的左上位置。
Canvas的使用(create_bitmap创建)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- img = PhotoImage(file="1.gif")
- w.create_image((,),image=img)
- master.mainloop()
Canvas的使用(create_image图片的使用)
- from tkinter import *
- master = Tk()
- w = Canvas(master,width=,height=)
- w.pack()
- def printCanvas():
- print("window")
- btn = Button(w,text="点我呀!",command=printCanvas)
- w.create_window((,),window=btn,anchor=W)
- w.create_line(,,,) #默认组件的优先级高,会覆盖重叠部分
- master.mainloop()
Canvas的使用(create_window组件的使用)
推文:
menu:菜单使用
- from tkinter import *
- master = Tk()
- def clb():
- print("dawfwa")
- menubar = Menu(master)
- #顶级菜单的创建
- menubar.add_command(label="hello",command=clb)
- menubar.add_command(label="quit",command=master.quit)
- master.config(menu=menubar)
- master.mainloop()
Menu的使用(顶级菜单的创建)
- from tkinter import *
- master = Tk()
- def callback():
- print("dawfwa")
- menubar = Menu(master)
- #子菜单
- filemenu = Menu(menubar,tearoff=False) #设置不可分离,不会在菜单界面显示一条虚线(可分离菜单窗口)
- filemenu.add_command(label="打开",command=callback)
- filemenu.add_command(label="保存",command=callback)
- filemenu.add_separator()
- filemenu.add_command(label="退出",command=master.quit)
- editmenu = Menu(menubar)
- editmenu.add_command(label="剪切",command=callback)
- editmenu.add_command(label="拷贝",command=callback)
- editmenu.add_command(label="复制",command=callback)
- #级联菜单
- #顶级菜单
- menubar.add_cascade(label="文件",menu=filemenu)
- menubar.add_cascade(label="编辑",menu=editmenu)
- #配置后才能显示
- master.config(menu=menubar)
- master.mainloop()
Menu的使用(级联菜单的创建:add_cascade)
- from tkinter import *
- master = Tk()
- def callback():
- print("dawfwa")
- menubar = Menu(master)
- menubar.add_command(label="查询",command=callback)
- menubar.add_command(label="重做",command=master.quit)
- frame = Frame(master,width=,height=)
- frame.pack()
- def popup(event):
- menubar.post(event.x,event.y)
- #post是相对于整个屏幕,而不是程序窗口,而event.x/y是获取的相对于程序窗口的尺寸,所以我们需要使用event.x_root/y_root去获取屏幕尺寸
- #frame是一个框架区域,其中可以包含其他控件,是一个独立的区域划分,我们在这个区域中绑定事件
- frame.bind("<Button-3>",popup) #-1是左键,-2是中间滑轮点击,-3是右键
- master.config(menu=menubar)
- master.mainloop()
Menu的使用(点击弹出菜单post)
- from tkinter import *
- master = Tk()
- def callback():
- print("dawfwa")
- menubar = Menu(master)
- openvar = IntVar()
- savevar = IntVar()
- quitvar = IntVar()
- #子菜单
- filemenu = Menu(menubar,tearoff=False) #设置不可分离,不会在菜单界面显示一条虚线(可分离菜单窗口)
- filemenu.add_checkbutton(label="打开",command=callback,variable=openvar)
- filemenu.add_checkbutton(label="保存",command=callback,variable=savevar)
- filemenu.add_separator()
- filemenu.add_checkbutton(label="退出",command=master.quit,variable=quitvar)
- editvar = IntVar()
- editmenu = Menu(menubar)
- editmenu.add_radiobutton(label="剪切",command=callback,variable=editvar)
- editmenu.add_radiobutton(label="拷贝",command=callback,variable=editvar)
- editmenu.add_radiobutton(label="复制",command=callback,variable=editvar)
- #级联菜单
- #顶级菜单
- menubar.add_cascade(label="文件",menu=filemenu)
- menubar.add_cascade(label="编辑",menu=editmenu)
- master.config(menu=menubar)
- master.mainloop()
Menu的使用(级联菜单设置选中状态复选和单选)
- from tkinter import *
- master = Tk()
- def callback():
- print("dawfwa")
- mb = Menubutton(master,text=">",relief=RAISED)
- mb.pack()
- filenemu = Menu(mb,tearoff=False)
- #顶级菜单
- filenemu.add_command(label="文件",command=callback)
- filenemu.add_command(label="编辑",command=callback)
- mb.config(menu=filenemu)
- master.mainloop()
Menu的使用(Menubutton按钮菜单)
OptionMenu:实现下拉列表框(就是HTML中select)
- from tkinter import *
- OPTION = [
- "fawf",
- "",
- "fafwa2",
- ]
- master = Tk()
- v = StringVar()
- v.set("one")
- #def __init__(self, master, variable, value, *values, **kwargs):
- # w = OptionMenu(master,v,OPTION)
- #不加星号,进行解包,那么只能看做value被输出
- #加星号,列表被序列解包,正常输出*values
- w = OptionMenu(master,v,*OPTION)
- w.pack()
- master.mainloop()
OptionMenu的使用(参数序列解包)
事件处理(事件绑定bind)
- <modifier-type-detail>
- 事件序列是包含在<>中
- type部分是最重要的,他通常用于描述普通的事件类型
- modifier是可选的,用于描述组合键Ctrl+C,Ctrl+Shift...
- detail也是可选的,他通常用于描述具体的按键,<Button-> 1代表左键 中间滚轮 右键
- class Misc:
- """Internal class.
- Base class which defines methods common for interior widgets."""
- def bind(self, sequence=None, func=None, add=None):
- """Bind to this widget at event SEQUENCE a call to function FUNC.
- SEQUENCE is a string of concatenated event
- patterns. An event pattern is of the form
- <MODIFIER-MODIFIER-TYPE-DETAIL> where MODIFIER is one
- of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4,
- Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3,
- B3, Alt, Button4, B4, Double, Button5, B5 Triple,
- Mod1, M1. TYPE is one of Activate, Enter, Map,
- ButtonPress, Button, Expose, Motion, ButtonRelease
- FocusIn, MouseWheel, Circulate, FocusOut, Property,
- Colormap, Gravity Reparent, Configure, KeyPress, Key,
- Unmap, Deactivate, KeyRelease Visibility, Destroy,
- Leave and DETAIL is the button number for ButtonPress,
- ButtonRelease and DETAIL is the Keysym for KeyPress and
- KeyRelease. Examples are
- #可以进行事件组合
- <Control-Shift-KeyPress-H>:用户同时按下Ctrl+Shift+H才会触发
- <Control-Button-> for pressing Control and mouse button or
- <Alt-A> for pressing A and the Alt key (KeyPress can be omitted).
- An event pattern can also be a virtual event of the form
- <<AString>> where AString can be arbitrary. This
- event can be generated by event_generate.
- If events are concatenated they must appear shortly
- after each other.
- FUNC will be called if the event sequence occurs with an
- instance of Event as argument. If the return value of FUNC is
- "break" no further bound function is invoked.
- An additional boolean parameter ADD specifies whether FUNC will
- be called additionally to the other bound function or whether
- it will replace the previous function.
- Bind will return an identifier to allow deletion of the bound function with
- unbind without memory leak.
- If FUNC or SEQUENCE is omitted the bound function or list
- of bound events are returned."""
- return self._bind(('bind', self._w), sequence, func, add)
可以绑定的事件
- class Event:
- """Container for the properties of an event.
- Instances of this type are generated if one of the following events occurs:
- KeyPress, KeyRelease - for keyboard events
- ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events
- Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate,
- Colormap, Gravity, Reparent, Property, Destroy, Activate,
- Deactivate - for window events.
- If a callback function for one of these events is registered
- using bind, bind_all, bind_class, or tag_bind, the callback is
- called with an Event as first argument. It will have the
- following attributes (in braces are the event types for which
- the attribute is valid):
- serial - serial number of event
- num - mouse button pressed (ButtonPress, ButtonRelease)
- focus - whether the window has the focus (Enter, Leave)
- height - height of the exposed window (Configure, Expose)
- width - width of the exposed window (Configure, Expose)
- keycode - keycode of the pressed key (KeyPress, KeyRelease)
- state - state of the event as a number (ButtonPress, ButtonRelease,
- Enter, KeyPress, KeyRelease,
- Leave, Motion)
- state - state as a string (Visibility)
- time - when the event occurred
- x - x-position of the mouse
- y - y-position of the mouse
- x_root - x-position of the mouse on the screen
- (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
- y_root - y-position of the mouse on the screen
- (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion)
- char - pressed character (KeyPress, KeyRelease)
- send_event - see X/Windows documentation
- keysym - keysym of the event as a string (KeyPress, KeyRelease)
- keysym_num - keysym of the event as a number (KeyPress, KeyRelease)
- type - type of the event as a number
- widget - widget in which the event occurred
- delta - delta of wheel movement (MouseWheel)
- """
- pass
Event事件的所有参数
- from tkinter import *
- master = Tk()
- def callback(event):
- print("点击位置:",event.x,event.y)
- frame = Frame(master,width=,height=)
- frame.pack()
- #绑定事件
- frame.bind("<Button-1>",callback) #鼠标左键
- frame.bind("<Button-2>",callback) #鼠标滚轮
- frame.bind("<Button-3>",callback) #鼠标右键
- master.mainloop()
鼠标点击事件
- from tkinter import *
- master = Tk()
- def callback(event):
- # print("获取的键盘值:",event.keysym) #可以获取所有的键盘值,但是对于输入法输入的中文等不能识别,为??
- # print("获取的输入值:",event.char) #获取用户输入,对于特殊,像shift等是不能捕获,为空
- char = event.char
- if not char:
- char = event.keysym
- print("获取的值:",char)
- frame = Frame(master,width=,height=)
- frame.pack()
- #绑定事件
- frame.bind("<KeyRelease>",callback) #键盘按键Key, KeyPress, KeyRelease
- frame.focus_set()
- master.mainloop()
键盘按键消息
....其他看上面红色部分
其他组件:
- from tkinter import *
- master = Tk()
- m = Message(master,text="fafw\ndwafawfawfawfwafawffwafaw",width=)
- m.pack()
- master.mainloop()
Message组件(是label组件的变体:允许多行输出)
- from tkinter import *
- master = Tk()
- # sx = Spinbox(master,from_=,to=) #-
- # sx.pack()
- sx = Spinbox(master,values=("dasf","fafw","gea"))
- sx.pack()
- master.mainloop()
Spinbox组件(是Entry的变体:允许进行选择)
- #coding:utf-
- from tkinter import *
- master = Tk()
- #PanedWindow和Frame相似,都是未组件提供一个框架,不过PanedWindow允许用户调整应用程序得空间划分
- pw = PanedWindow(orient=VERTICAL)
- pw.pack()
- top = Label(pw,text="top paned")
- pw.add(top)
- bottom = Label(pw,text="Bottom paned")
- pw.add(bottom)
- master.mainloop()
PanedWindow组件(PanedWindow和Frame相似,都是未组件提供一个框架,不过PanedWindow允许用户调整应用程序得空间划分)
- #coding:utf-
- from tkinter import *
- master = Tk()
- #PanedWindow和Frame相似,都是未组件提供一个框架,不过PanedWindow允许用户调整应用程序得空间划分
- pw1 = PanedWindow(showhandle=True,sashrelief=SUNKEN) #默认水平 showhandle显示手柄,sashrelief显示边框
- pw1.pack(fill=BOTH,expand=)
- left = Label(pw1,text="left paned")
- pw1.add(left)
- pw2 = PanedWindow(orient=VERTICAL,showhandle=True,sashrelief=SUNKEN)
- pw1.add(pw2)
- top = Label(pw2,text="top paned")
- bottom = Label(pw2,text="bottom paned")
- pw2.add(top)
- pw2.add(bottom)
- master.mainloop()
PanedWindow组件(布局了解下)
- #coding:utf-
- from tkinter import *
- master = Tk()
- #Toplevel创建顶级窗口
- def create():
- top = Toplevel()
- top.attributes("-alpha",0.5) #加-的原因是:最后是以命令行去调用Windows sdk alpha是透明度
- top.title("hello")
- msg = Message(top,text="gegaegagagag\nagfawfa")
- msg.pack()
- Button(master,text="create",command=create).pack()
- master.mainloop()
Toplevel组件(创建顶级窗口)
三种标准对话框模块
- messagebox
- filedialog
- colorchooser
在低版本中这三个对话框放在不同的模块tkMessageBox,tkFileDialog,tkColorChooser
- from tkinter import *
- from tkinter import messagebox
- master = Tk()
- ret = messagebox.askokcancel("title","question")
- #askyesno
- #askretrycancel
- #上面返回布尔型
- #showerror
- #showinfo
- #showwarning
- #返回OK表示按下了是
- #askquestion
- #返回yes或者no表示点击是或否
- print(ret)
- master.mainloop()
messagebox对话框
- filedialog模块提供两个函数askopenfilename和asksaveasfilename()
- 分别用于打开文件和保存文件
- from tkinter import *
- from tkinter import filedialog
- master = Tk()
- def callback():
- filename = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GIF",".gif"),("JPG",".jpg")])
- print(filename)
- Button(master,text="open file",command=callback).pack()
- master.mainloop()
filetypes文件类型过滤
- from tkinter import *
- from tkinter import filedialog
- master = Tk()
- def callback():
- filename = filedialog.askopenfilename(defaultextension=".png")
- print(filename)
- #defaultextension设置默认后缀,不能对文件起到过滤,只是当你选择文件未写后缀的话为你加上defaultextension,再进行筛选
- Button(master,text="open file",command=callback).pack()
- master.mainloop()
defaultextension设置默认后缀
- initialdir:设置默认打开文件夹目录
- title:设置标题
- parent:设置父窗口,默认根窗口
- from tkinter import *
- from tkinter import colorchooser
- master = Tk()
- def callback():
- color= colorchooser.askcolor()
- print(color)
- #((109.42578125, 115.44921875, 211.82421875), '#6d73d3') rgb和16进制值
- Button(master,text="choose color",command=callback).pack()
- master.mainloop()
colorchooser对话框
暂时完成。 还有其他工具包PyQT和PyGTK也是使用十分广泛的。
python---基础知识回顾(九)图形用户界面-------Tkinter的更多相关文章
- python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。
本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...
- python基础知识回顾之列表
在python 中,主要的常用数据类型有列表,元组,字典,集合,字符串.对于这些基础知识,应该要能够足够熟练掌握. 如何创建列表: # 创建一个空列表:定义一个变量,然后在等号右边放一个中括号,就创建 ...
- python基础教程总结11——图形用户界面GUI
1. 丰富的平台 工具包 描述 Tkinter 使用Tk平台.很容易得到.半标准. wxpython 基于wxWindows.跨平台越来越流行. PythonWin 只能在Windows上使用.使用了 ...
- python基础知识回顾之字符串
字符串是python中使用频率很高的一种数据类型,内置方法也是超级多,对于常用的方法,还是要注意掌握的. #author: Administrator #date: 2018/10/20 # pyth ...
- python基础知识回顾之元组
元组与列表的方法基本一样,只不过创建元组是用小括号()把元素括起来,两者的区别在于,元组的元素不可被修改. 元组被称为只读列表,即数据可以被查询,但不能被修改,列表的切片操作适用于元组. 元组写在小括 ...
- python基础知识回顾[1]
1.声明变量 # 声明一个变量name用来存储一个字符串'apollo' name = 'apollo' # 声明一个变量age用来存储一个数字20 age = 20 # 在控制台打印变量name中存 ...
- python基础知识小结-运维笔记
接触python已有一段时间了,下面针对python基础知识的使用做一完整梳理:1)避免‘\n’等特殊字符的两种方式: a)利用转义字符‘\’ b)利用原始字符‘r’ print r'c:\now' ...
- Python 基础知识(一)
1.Python简介 1.1.Python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为了在阿姆斯特丹打发时 ...
- Python基础知识(五)
# -*- coding: utf-8 -*-# @Time : 2018-12-25 19:31# @Author : 三斤春药# @Email : zhou_wanchun@qq.com# @Fi ...
- scrapy实战1,基础知识回顾和虚拟环境准备
视频地址 https://coding.imooc.com/learn/list/92.html 一. 基础知识回顾 1. 正则表达式 1)贪婪匹配,非贪婪匹配 .*? 非贪婪 . ...
随机推荐
- 团队冲刺--six
昨天: 司宇航:合并版块,但部分有缺陷. 马佳慧:研究css. 王金萱:写注册界面. 季方: 研究爬虫,精确的处理数据. 今天: 司宇航:测试功能版块,优化功能版块. 马佳慧:优化界面 . 王金萱: ...
- 冲刺One之站立会议6 /2015-5-19
2015-5-19 今天把服务器端的界面完善了一下,然后大家查了好多资料,实现了登陆界面实际连接的功能,开始加了一个它和服务器的的跳转,但是分析过后发现这是个没有必要的跳转.登录应该直接转到聊天室的主 ...
- Java导出引用jar包的文件
安装Eclipse打包插件Fat Jar 方案一对于含有较多第三方jar文件或含有第三方图片资源等就显得不合适,太繁琐.这时可以使用一个打包的插件-Fat Jar. Fat Jar ...
- The last time the sprint(最后一个冲刺)
经过一两个月的努力,我们终于是做出来了一点东西,从一开始接触这个项目开始,从完全不知道怎么去入手到跌跌碰碰,再到现在可以拿出来一点东西给别人看,我觉得很开心,或许我的这个成品在别人眼中并不算是什么,但 ...
- C# 通过http post 请求上传图片和参数
一.C# Winform或控制台 /// <summary> /// 通过http上传图片及传参数 /// </summary> /// <param name=&quo ...
- PAT 1068 万绿丛中一点红
https://pintia.cn/problem-sets/994805260223102976/problems/994805265579229184 对于计算机而言,颜色不过是像素点对应的一个 ...
- centos6.7 安装JDK
1.卸载JDK 查看系统是否已安装JDK.一般的linux都默认使用了开源的openJDK.显示JDK版本信息,已经安装JDK,否则没有安装.命令行: [root@localhost ~]# ja ...
- java 数据结构与算法---栈
原理来自百度百科 一.栈的定义 栈是一种只能在一端进行插入和删除操作的特殊线性表:它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数 ...
- java中的==操作符和equals函数
基本规则 “==”操作符的使用需要分成两种情况 判值类型相等 这一点很好理解,两个值类型代表的数值相等,则“==”表达式返回true “==”可以用与不同值类型的比较,语言会自动进行类型转换 判引用类 ...
- Cent7安装mysql5.7.11全过程
下载mysql(注:其他版本未测试) https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-5.7.11.tar.gz 1.安装依赖包 yum -y ...