初识GUI编程之tkinter(1)

来源:互联网 发布:西门子模拟量编程实例 编辑:程序博客网 时间:2024/05/10 11:56

因为最近做的一个项目要供用户使用,理所当然得做出图形化界面给用户提供方便,所以初次了解就暂时整理了如下资料:

 

GUI(graphics user interface )图形用户界面

 

GUI是指采用图形方式显示的计算机操作用户界面。基于图形的界面,windows就是一个图形用户界面的操作系统,而DOS是基于命令提示符的操作系统。

图形界面对于用户来说在视觉上更易于接受。

 

Python的GUI编程

 

python提供了多个图形开发界面的库,几个常用Python GUI库如下:

 

tkinter: Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口,是内置于python中的,使用前不需要安装,能满足绝大部分GUI编程需要。

wxPython:wxPython是一款开源软件,是 Python 语言的一套优秀的 GUI 图形库,允许 Python 程序员很方便的创建完整的、功能键全的 GUI 用户界面。

PyQt是Qt库的Python版本。PyQt3支持Qt1到Qt3。 PyQt4支持Qt4。它的首次发布也是在1998年,但是当时它叫 PyKDE,因为开始的时候SIP和PyQt没有分开。PyQt是用SIP写的。PyQt 提供 GPL版和商业版。


Tkinter 组件

Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用。这些控件通常被称为控件或者部件。

目前有15Tkinter的部件。我们提出这些部件以及一个简短的介绍,在下面的表:

控件

描述

Button

按钮控件;在程序中显示按钮。

Canvas

画布控件;显示图形元素如线条或文本

Checkbutton

多选框控件;用于在程序中提供多项选择框

Entry

输入控件;用于显示简单的文本内容

Frame

框架控件;在屏幕上显示一个矩形区域,多用来作为容器

Label

标签控件;可以显示文本和位图

Listbox

列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户

Menubutton

菜单按钮控件,由于显示菜单项。

Menu

菜单控件;显示菜单栏,下拉菜单和弹出菜单

Message

消息控件;用来显示多行文本,与label比较类似

Radiobutton

单选按钮控件;显示一个单选的按钮状态

Scale

范围控件;显示一个数值刻度,为输出限定范围的数字区间

Scrollbar

滚动条控件,当内容超过可视化区域时使用,如列表框。.

Text

文本控件;用于显示多行文本

Toplevel

容器控件;用来提供一个单独的对话框,和Frame比较类似

Spinbox

输入控件;与Entry类似,但是可以指定输入范围值

PanedWindow

PanedWindow是一个窗口布局管理的插件,可以包含一个或者多个子控件。

LabelFrame

labelframe 是一个简单的容器控件。常用与复杂的窗口布局。

tkMessageBox

用于显示你应用程序的消息框。


标准属性

标准属性也就是所有控件的共同属性,如大小,字体和颜色等等。

属性

描述

Dimension

控件大小;

Color

控件颜色;

Font

控件字体;

Anchor

锚点;

Relief

控件样式;

Bitmap

位图;

Cursor

光标;


几何管理

Tkinter控件有特定的几何状态管理方法,管理整个控件区域组织,一下是Tkinter公开的几何管理类:包、网格、位置

几何方法

描述

pack()

包装;

grid()

网格;

place()

位置;



label&button用法

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()#窗口名字window.title("my window")#窗口大小window.geometry('300x100')#将字符串的变量表示tk中特定的形式var = tk.StringVar()#传入窗体对象,显示文本,背景颜色,字体,label长高label =tk.Label(master=window,textvariable=var,bg='green',font=('Arial',12),width=15,height=2)label.pack()on_hit = Falsedef hit_me():    global on_hit    #以下条件判断点击一次显示var.set 第二次不显示    if on_hit == False:        on_hit = True        #将字符串设置为        var.set('you hit me')    else:        on_hit =False        var.set('')    #点击将会执行command所传的函数button = tk.Button(master=window,text="hit me",width=15,height=2,command=hit_me)button.pack()window.mainloop()

效果



Frame框架

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('350x350+800+400')tk.Label(master=window,text='on the window').pack()#定义主框架frm = tk.Frame(master=window)frm.pack()#次框架frm_l = tk.Frame(frm)frm_r = tk.Frame(frm)#side方向基于主frm的frm_l.pack(side='left')frm_r.pack(side='right')tk.Label(master=frm_l,text='on the frm_l1').pack()tk.Label(master=frm_l,text='on the frm_l2').pack()tk.Label(master=frm_r,text='on the frm_r1').pack()window.mainloop()
显示效果



Entry&Text

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('200x200')#show表示输入的字符显示为你所指定的,隐藏功能entry = tk.Entry(master=window,show='*')entry.pack()#insert可以指定插入到你所指定的位置,在文本框中鼠标所指位置将会作为插入地址def insert_point():    var = entry.get()    t.insert('insert',var)def insert_end():    var = entry.get()    t.insert('end',var)   # t.insert(1.1,var)#表示在第一行第一列插入button1 = tk.Button(master=window,text='insert point',width= 15,height=2,command=insert_point)button1.pack()button2 = tk.Button(master=window,text='insert end',command=insert_end)button2.pack(padx=20, side='left')t= tk.Text(master=window,height=2)t.pack()window.mainloop()

checkbutton勾选

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('300x300')l =tk.Label(master=window,width=25,bg='yellow',text='empty')l.pack()def print_selection():    if(var1.get() == 1) & (var2.get() == 0):        l.config(text='I love only Python')    elif(var1.get() == 0) & (var2.get() == 1):        l.config(text='I love only C++')    elif(var1.get() == 0) & (var2.get() == 0):        l.config(text='I do not love either')    else:        l.config(text='I love both')var1 =tk.IntVar()var2 =tk.IntVar()#选定Pythonvariable将绑定,onvalue=1,offvalue=0,此时=1会赋值给var1c1 = tk.Checkbutton(master=window,text='Python',variable=var1,onvalue=1,offvalue=0,command=print_selection)c2 = tk.Checkbutton(master=window,text='C++',variable=var2,onvalue=1,offvalue=0,command=print_selection)c1.pack()c2.pack()window.mainloop()


Canvas画布

请注意只能添加GIF格式和BMP的,但是我只测试过gif的,仅仅修改后缀也是没用的,也会提示找不到该文件

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('200x200')canvas = tk.Canvas(master=window,bg='blue',height=100,width=200)#打开存放的图片image_file = tk.PhotoImage(master=window,file='2qq.gif')#定义所放画布的点image = canvas.create_image(10,10,anchor='nw',image=image_file)x0,y0,x1,y1 = 50,50,80,80line = canvas.create_line(x0,y0,x1,y1)canvas.pack()b = tk.Button(master=window,text='move').pack()window.mainloop()




Menubar菜单

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('350x350+800+400')l = tk.Label(master=window,text='',bg='yellow')l.pack()count=0def do_job():    global count    #config改变Label的参数    l.config(text='do'+str(count))    count+=1#定义Mwnu顶级菜单menubar = tk.Menu(master=window)#tearoff设置为1时表示菜单可独立出来,或者False# 创建一个下拉菜单“文件”,然后将它添加到顶级菜单中filemenu = tk.Menu(menubar,tearoff=0)menubar.add_cascade(label='File',menu=filemenu)filemenu.add_command(label='New',command=do_job)filemenu.add_command(label='Open',command=do_job)filemenu.add_command(label='Save',command=do_job)#表示加条分割线filemenu.add_separator()filemenu.add_command(label='Exit',command=window.quit)editmenu = tk.Menu(menubar,tearoff=0)menubar.add_cascade(label='Edit',menu=filemenu)editmenu.add_command(label='Cut',command=do_job)editmenu.add_command(label='Copy',command=do_job)editmenu.add_command(label='Paste',command=do_job)#在filemenu中创建多级菜单submenu = tk.Menu(filemenu,tearoff=False)#underline,指字体下划线,如果1(True)则加下划线默认为0(Fasle)filemenu.add_cascade(label='Import',menu=submenu,underline=0)submenu.add_command(label='Submenu1',command=do_job)#显示菜单window.config(menu=menubar)window.mainloop()



Listbox列表部件

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('500x300')var1 =tk.StringVar()label = tk.Label(master=window,bg='yellow',width=5,textvariable=var1)label.pack()#insert可以指定插入到你所指定的位置,在文本框中鼠标所指位置将会作为插入地址def print_selection():    #表示光标所选定的东西    value = lb.get(lb.curselection())    var1.set(value)button1 = tk.Button(master=window,text='print selection',width= 15,height=2,command=print_selection)button1.pack()var2 = tk.StringVar()var2.set((11,22,33,44))lb = tk.Listbox(master=window,listvariable=var2)list_items = [1,2,3,4]for item in list_items:    lb.insert('end',item)lb.insert(1,'first')lb.insert(2,'second')lb.delete(2)lb.pack()t= tk.Text(master=window,height=2)t.pack()window.mainloop()



pack,place,grid布局,

布局中只能选择一个函数进行布局,不能混合使用

优先现则grid布局,更方便

#-*-coding:utf-8-*-#注意:不要试图在一个主窗口中混合使用pack和gridimport tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('200x200+450+350')# for i in range(4):#     for j in range(3):#         #pady表示y轴间距为10#         tk.Label(master=window,text=1).grid(row=i,column=j,pady=10,padx=10)#place表示放在单独的坐标,较为精准# tk.Label(master=window,text=1).place(x=10,y=100,anchor='nw')tk.Label(master=window,text=1).pack(side='top')tk.Label(master=window,text=2).pack(side='bottom')tk.Label(master=window,text=3).pack(side='left')tk.Label(master=window,text=4).pack(side='right')window.mainloop()



Radiobutton选择按钮

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('400x400')var= tk.StringVar()l = tk.Label(master=window,bg='yellow',width=25,text='empty')l.pack()def print_selection():    #所以的参数都是可以改变的    l.config(text='you have selected' + var.get())r1 = tk.Radiobutton(master=window,text='Option A',variable=var,value='A',command=print_selection)#vard的值存放在valuer1.pack()r2 = tk.Radiobutton(master=window,text='Option B',variable=var,value='B',command=print_selection)#vard的值存放在valuer2.pack()r3 = tk.Radiobutton(master=window,text='Option C',variable=var,value='C',command=print_selection)#vard的值存放在valuer3.pack()window.mainloop()


Scale尺度

#-*-coding:utf-8-*-import tkinter as tkwindow = tk.Tk()window.title('my window')window.geometry('400x400')l = tk.Label(master=window,bg='yellow',width=25,text='empty')l.pack()def print_selection(v):    l.config(text='you have selected'+ v)#进度条的名字和取值范围,orient=tk.HORIZONTAL表示方向为横向,像素宽度200,showvalue表示每次拖动显示数值,tickinterval标签间隔长度,resolution表示保留两位小数s = tk.Scale(master=window,label='try me',from_=5,to=11,orient=tk.HORIZONTAL,length=200,showvalue=1,tickinterval=3,resolution=0.01,command=print_selection)s.pack()window.mainloop()





下面是结合多种组件实现的计算器

#-*-coding:utf-8-*-from tkinter import *from tkinter.ttk import *def frame(master):    """将共同的属性作为默认值, 以简化Frame创建过程"""    w = Frame(master)    w.pack(side=TOP, expand=1, fill=BOTH)    return w#expand置1 使能fill属性# expand置0 关闭fill属性# fill=X        当GUI窗体大小发生变化时,widget在X方向跟随GUI窗体变化# fill=Y       当GUI窗体大小发生变化时,widget在Y方向跟随GUI窗体变化# fill=BOTH 当GUI窗体大小发生变化时,widget在X、Y两方向跟随GUI窗体变化def button(master, text, command):    """提取共同的属性作为默认值, 使Button创建过程简化"""    w = Button(master, text=text, command=command, width=6)    w.pack(side=LEFT, expand=YES, fill=BOTH, padx=2, pady=2)    return wdef back(text):    """将text最末的字符删除并返回"""    if len(text) > 0:        return text[:-1]    else:        return textdef calc(text):    """用eval方法计算表达式字符串"""    try:        if (sep_flag.get() == 0):            return eval(del_sep(text))        else:            return add_sep(str(eval(del_sep(text))))    except (SyntaxError, ZeroDivisionError, NameError):        return 'Error'def add_sep(text):    """向参数传入的数字串中添加千位分隔符    这里考虑了三种情况: 无整数部份, 无小数部份, 同时有整数和小数部份    由于字符串是不可改变的, 这里由字符串生成列表以便执行insert操作和    extend操作, 操作完成后最由列表生成字符串返回    """    dot_index = text.find('.')    if dot_index > 0:        text_head = text[:dot_index]        text_tail = text[dot_index:]    elif dot_index < 0:        text_head = text        text_tail = ''    else:        text_head = ''        text_tail = text    list_ = [char for char in text_head]    length = len(list_)    tmp_index = 3    while length - tmp_index > 0:        list_.insert(length - tmp_index, ',')        tmp_index += 3    list_.extend(text_tail)    new_text = ''    for char in list_:        new_text += char    return new_textdef del_sep(text):    """删除数字串中所有的千位分隔符"""    return text.replace(',', '')# 开始界面的实现root = Tk()root.title("Calculator") # 添加标题main_menu = Menu() # 创建最上层主菜单# 创建Calculator菜单, 并加入到主菜单calc_menu = Menu(main_menu, tearoff=0)calc_menu.add_command(label='Quit', command=lambda: exit())main_menu.add_cascade(label='Calculator', menu=calc_menu)# 创建View菜单, 并加入到主菜单# 其中"Show Thousands Separator"菜单项是一个Checkbuttontext = StringVar()sep_flag = IntVar()sep_flag.set(0)view_menu = Menu(main_menu, tearoff=0)view_menu.add_checkbutton(label='Show Thousands Separator', variable=sep_flag,                          command=lambda t=text: t.set(add_sep(t.get())))main_menu.add_cascade(label='View', menu=view_menu)root['menu'] = main_menu # 将主菜单与root绑定# 创建文本框Entry(root, textvariable=text).pack(expand=YES, fill=BOTH, padx=2, pady=4)style = Style()style.configure('TButton', padding=3)# 创建第一行三个按钮fedit = frame(root)#将输入文本框中字符赋给t,button(fedit, 'Backspace', lambda t=text: t.set(back(t.get())))button(fedit, 'Clear', lambda t=text: t.set(''))button(fedit, '±', lambda t=text: t.set('-('+t.get()+')'))# 每行四个, 创建其余四行按钮for key in ('789/', '456*', '123-', '0.=+'):    fsymb = frame(root)    for char in key:        if char == '=':            button(fsymb, char, lambda t=text: t.set(calc(t.get())))        else:            button(fsymb, char, lambda t=text, c=char: t.set(t.get()+c))root.mainloop()



0 0