到目前为止,我们所编写的Python代码都是处于一个文字交互界面的状态。但在实际应用中,很多用户都是非专业的,他们希望所提供的软件能有一个友好的界面,这就用到GUI编程了。
GUI(Graphical User Interface)又称图形用户界面,是指采用图形方式显示的用户操作界面。Python的GUI工具包有很多,其中最常用的有tkinter,wxPython,PyGTK,PyQt等,本章将介绍如何使用tkinter来编写GUI程序。
tkinter是Python的标准GUI库。
tkinter的优点是简单易用,与Python结合度好。
tkinter在Python 3.x下默认集成,不需要额外安装。因此,想要使用tkinter进行GUI编程,可直接使用import语句导入tkinter模块。
import tkinter
1,导入tkinter模块(import tkinter)
2,创建一个顶层窗口对象(调用Tk()函数),用于容纳整个GUI应用
3,在顶层窗口对象上构建所有的GUI控件
4,进入主事件循环(调用mainloop()函数)
5,通过底层应用代码将这些GUI控件连接起来
第一个tkinter实例——创建一个窗口用于输出“Hello world“。(示例):
import tkinter #导入tkinter模块
top = tkinter.Tk() #创建一个顶层窗口对象
label = tkinter.Label(top,text='Hello World',fg='red')#添加一个Label控件,用于显示文本
label.pack() #调用Label控件的pack()方法
top.mainloop() #进入主事件循环
1,在GUI编程中,顶层窗口对象包含组成GUI应用程序的所有小窗口对象,它们可能是文字标签、按钮、列表框等,这些独立的GUI组件称为控件。
窗口中可包含标签、菜单、按钮等其他控件,其运行之后可移动和缩放。
例:创建一个300×200的窗口,其标题为“金企鹅”,运行后该窗口宽不可变,高可变。
import tkinter #导入tkinter库
window = tkinter.Tk() #创建tkinter对象
window.title("金企鹅") #设置标题
window.geometry("300x200") #设置窗口大小,注意是字母x
window.resizable(width=False, height=True) #宽不可变,高可变,默认为True
window.mainloop() #进入主事件循环
Label控件是用于在界面上输出描述信息的标签,可以显示文本和图像。
例:创建一个200×100的窗口,其标题为“金企鹅”,在窗口中创建一个标签,用于显示“金企鹅联合出版中心”,并设置其字体、颜色、宽度和高度。
import tkinter #导入tkinter库
window = tkinter.Tk() #创建tkinter对象
window.title("金企鹅") #设置标题
window.geometry("200x100") #设置窗口大小,注意是字母x
#创建标签,text设置文本,bg设置背景色,fg设置前景色,font设置字体,width设置宽,height设置高
label1 = tkinter.Label(window, text="金企鹅联合出版中心", bg="white", fg="blue", font=("宋体"), width=20, height=3)
label1.pack() #显示Label
window.mainloop() #进入主事件循环
通过Button控件可以方便地与用户进行交互。Button控件有一个command属性,用于指定一个函数或方法,当用户单击按钮时,tkinter就会自动调用该函数或方法。
例:编写程序实现通过按下按钮来执行指定操作(改变标签的内容)。
import tkinter as tk #导入tkinter模块重命名为tk
#定义函数,用于实现改变标签的内容
def btnHelloClicked():
labelHello.config(text = "Hello tkinter!")
top = tk.Tk() #创建tkinter对象
top.geometry("200x150") #设置窗口大小,注意是字母x
top.title("Button Test") #设置窗口标题
#创建原始标签
labelHello = tk.Label(top, text = "Press the button...", height = 5, width = 20, fg = "blue")
labelHello.pack() #显示标签
#创建按钮,显示“Hello”,单击按钮调用btnHelloClicked函数
btn = tk.Button(top, text = "Hello", command = btnHelloClicked)
btn.pack() #显示按钮
top.mainloop() #进入主事件循环
Entry控件就是输入框,用来输入单行内容,可以方便地向程序传递用户参数。获取输入框的内容可以使用Entry控件的get()方法。
例:编写摄氏度转华氏度的小程序,要求从输入框输入摄氏度的值,单击计算按钮后得到华氏度的值。计算公式:F = 1.8×C+32。
import tkinter as tk #导入并重命名tkinter模块
#定义函数用于读取Entry控件的内容并将计算结果进行输出
def btnHelloClicked():
cd = float(entryCd.get()) #读取Entry控件的内容
labelHello.config(text = "%.2f°C = %.2f°F" %(cd, cd*1.8+32))
top = tk.Tk() #创建tkinter对象
top.title("Entry Test") #设置窗口标题
#创建标签
labelHello = tk.Label(top, text = "摄氏度转华氏度", height = 5, width = 20, fg = "blue")
labelHello.pack() #显示标签
entryCd = tk.Entry(top, text = "0") #创建输入框
entryCd.pack() #显示输入框
#创建按钮
btnCal = tk.Button(top, text = "计算", command = btnHelloClicked)
btnCal.pack() #显示按钮
top.mainloop() #进入主事件循环
Radiobutton和Checkbutton控件分别用于实现选项的单选和复选功能。
例:编写程序,实现通过单选框和复选框设置文字样式的功能。
import tkinter as tk #导入tkinter模块重命名为tk
#定义函数用于修改标签中文字的颜色
def colorChecked():
labelHello.config(fg = color.get())
#定义函数用于修改标签中文字的字体
def typeChecked():
textType = typeBlod.get() + typeItalic.get() #两个复选框的值相加
if textType == 1: #单选typeBlod复选框
labelHello.config(font = ("Arial", 12, "bold"))
elif textType == 2: #单选typeItalic复选框
labelHello.config(font = ("Arial", 12, "italic"))
elif textType == 3: #同时选中两个复选框
labelHello.config(font = ("Arial", 12, "bold italic"))
else: #两个都不选
labelHello.config(font = ("Arial", 12))
top = tk.Tk() #创建tkinter对象
top.title("Radio & Check Test") #设置窗口标题
#创建标签
labelHello = tk.Label(top, text = "Check the format of text.", height = 3, font=("Arial", 12))
labelHello.pack() #显示标签
color = tk.StringVar() #获取单选框输入
#创建三个单选框并显示
tk.Radiobutton(top, text = "Red", variable = color, value = "red", command = colorChecked).pack()
tk.Radiobutton(top, text = "Blue", variable = color, value = "blue", command = colorChecked).pack()
tk.Radiobutton(top, text = "Green", variable = color, value = "green", command = colorChecked).pack()
#获取复选框输入
typeBlod = tk.IntVar()
typeItalic = tk.IntVar()
#创建2个复选框
tk.Checkbutton(top, text = "Blod", variable = typeBlod, onvalue = 1, offvalue = 0, command = typeChecked).pack()
tk.Checkbutton(top, text = "Italic", variable = typeItalic, onvalue = 2, offvalue = 0, command = typeChecked).pack()
top.mainloop() #进入主事件循环
(提示)可以使用tkinter.StringVar()创建与特定控件关联的字符串变量,使用tkinter.IntVar()创建与特定控件关联的整型变量。
tkinter提供了Menu控件,用于实现顶级菜单、下拉菜单和弹出菜单。
创建一个顶级菜单,需要先创建一个菜单实例,然后使用add()方法将命令添加进去。
import tkinter #导入tkinter库
#定义函数用于显示信息
def callback():
print('单击了“显示”菜单!')
window = tkinter.Tk() #创建tkinter对象
window.title("标题") #设置标题
window.geometry("200x100") #设置窗口大小
menubar = tkinter.Menu(window) #创建一个顶级菜单窗口
#给菜单实例增加菜单项
menubar.add_command(label='显示', command = callback)
menubar.add_command(label='退出', command = window.quit)
window.config(menu = menubar) #显示菜单
window.mainloop() #进入主事件循环
创建一个下拉菜单,方法同创建顶级菜单类似,最主要的区别是下拉菜单需要添加到主菜单上。
import tkinter
window = tkinter.Tk()
window.title("标题")
window.geometry("200x100")
#创建一个顶级菜单实例
menubar = tkinter.Menu(window)
#为每个子菜单实例添加菜单项
#创建文件菜单项,并添加子菜单
fmenu = tkinter.Menu(menubar)
for each in ['新建','打开','保存','另存为']:
fmenu .add_command(label = each)
#创建视图菜单项,并添加子菜单
vmenu = tkinter.Menu(menubar)
for each in ['复制','粘贴','剪切']:
vmenu.add_command(label = each)
#创建编辑菜单项,并添加子菜单
emenu = tkinter.Menu(menubar)
for each in ['默认视图','新式视图']:
emenu.add_command(label = each)
#创建关于菜单项,添加子菜单
amenu = tkinter.Menu(menubar)
for each in ['版权信息','联系我们']:
amenu.add_command(label = each)
#为顶级菜单实例添加菜单,并绑定相应的子菜单实例
menubar.add_cascade(label='文件',menu=fmenu)
menubar.add_cascade(label='视图',menu=vmenu)
menubar.add_cascade(label='编辑',menu=emenu)
menubar.add_cascade(label='关于',menu=amenu)
window.config(menu = menubar) #显示菜单
window.mainloop() #进入主事件循环
创建一个弹出菜单的方法也是类似的,不过需要使用post()方法将其显示出来。
from tkinter import *
root = Tk()
#定义函数用于输出提示信息
def hello():
print( "选择了菜单!")
root.geometry("200x100")
#创建一个顶级菜单实例
menu = Menu(root)
menu.add_command(label="显示", command=hello)
menu.add_command(label="退出", command=root.quit)
#弹出菜单
frame = Frame(root, width=512, height=512)
frame.pack()
#定义函数,调用post()方法显示
def popup(event):
menu.post(event.x_root, event.y_root)
#绑定鼠标右键
frame.bind("" , popup)
root.config(menu = menu)
root.mainloop()
一个tkinter应用程序的大部分时间花费在事件循环上(通过mainloop()方法进入)。
事件可以有多种来源,包括用户触发的鼠标、键盘操作或是系统事件。
tkinter提供了强大的事件处理机制,对于每个控件来说,可以通过bind()方法将函数或方法绑定到具体的事件上,其语法格式如下:
控件对象名.bind(event, handler)
handler是一个处理函数或方法。event是tkinter已经定义好的事件(通过事件序列机制定义)。
例:捕获鼠标点击事件实例。
from tkinter import * #导入tkinter库中所有内容
root = Tk() #创建tkinter对象
#定义函数,用于输出鼠标单击的坐标
def callback(event):
print ("clicked at", event.x, event.y)
frame = Frame(root, width=200, height=100) #创建窗体
frame.bind("" , callback) #绑定鼠标左键
frame.pack() #显示窗体
root.mainloop() #进入主事件循环
tkinter使用一种称为事件序列的机制来允许用户定义事件,事件序列以字符串的形式表示,其语法格式如下:
modifier-type-detail
说明:
(1)事件序列必须用尖括号括起来;
(2)type字段是最重要的,它通常用于描述事件类型,如鼠标单击、键盘输入等;
(3)modifier字段是可选的,它通常用于描述组合键,如Ctrl、Shift等;
(4)detail字段也是可选的,它通常用于描述具体的按键,如Button-1表示单击鼠标左键。
type字段常用的关键字及含义:
modifier字段常用的关键字及含义
当tkinter调用预先定义的函数时,会将事件对象(作为参数)传递给函数,事件对象的属性及含义如下表所示。
例:事件绑定实例。
import tkinter #导入tkinter库
window = tkinter.Tk() #创建tkinter对象
window.title("标题") #设置标题
window.geometry("200x100") #设置窗口大小
#鼠标单击绑定事件
def func(event):
print("单击!")
window.bind("" ,func)
#鼠标双击绑定事件
def func1(event):
print("双击!")
window.bind("" ,func1)
#鼠标移入绑定事件
def func2(event):
print("鼠标移入!")
window.bind("" ,func2)
#实现拖拽功能
def func3(event):
x=str(event.x_root)
y=str(event.y_root)
window.geometry("200x100+"+x+"+"+y)
window.bind("" ,func3)
window.mainloop()
pack布局是按添加的顺序排列控件,即向容器中添加控件,第一个添加的控件在最上方,然后依次向下排列。
例:pack布局实例。
from tkinter import * #导入tkinter库中所有内容
root = Tk() #创建tkinter对象
#创建三个标签
Label(root, text = 'pack1', bg = 'red').pack()
Label(root, text = 'pack2', bg = 'blue').pack()
Label(root, text = 'pack3', bg = 'green').pack()
root.mainloop() #进入主事件循环
pack布局的常用属性:
(提示)pack布局适用于少量控件的排列,当界面复杂度增加时,要实现某种布局效果,需要分层来实现。
例:分层实现较复杂布局:
from tkinter import *
root = Tk()
root.title("Pack - Example")
#使用Frame增加一层容器
fm1 = Frame(root)
#创建3个按钮,从上到下排列
Button(fm1, text='Top').pack(side=TOP, anchor=W, fill=X)
Button(fm1, text='Center').pack(side=TOP, anchor=W, fill=X)
Button(fm1, text='Bottom').pack(side=TOP, anchor=W, fill=X)
fm1.pack(side=LEFT, fill=Y)
#使用Frame再增加一层容器
fm2 = Frame(root)
#创建3个按钮,从左到右排列
Button(fm2, text='Left').pack(side=LEFT)
Button(fm2, text='This is the Center button').pack(side=LEFT)
Button(fm2, text='Right').pack(side=LEFT)
fm2.pack(side=LEFT, padx=10)
root.mainloop()
grid布局又称为网格布局,是tkinter布局管理器中最灵活多变的布局方法。由于大多数程序界面都是矩形的,我们可以将它划分为由行和列组成的网格,然后根据行号和列号,将控件放置于网格之中。
属性如下:
例:grid布局实例代码如下:
from tkinter import * #导入tkinter库中所有内容
root = Tk() #创建tkinter对象
colours = ['red','green','orange','white','yellow','blue'] #定义颜色列表
r = 0
#循环创建标签和不同颜色的输入框
for c in colours:
Label(root,text=c, relief=RIDGE,width=15).grid(row=r,column=0)
Entry(root,bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)
r = r + 1
root.mainloop() #进入主事件循环
place布局使用控件坐标来放置控件的位置。
属性如下:
例:place布局实例代码如下:
from tkinter import * #导入tkinter库中所有内容
root = Tk() #创建tkinter对象
root.geometry("200x100") #设置窗口大小
la = Label(root,text = 'hello Place a') #创建标签la
la.place(x = 0,y = 0,anchor = NW) #使用绝对坐标将Label放置到(0,0)位置上
lb = Label(root,text = 'hello Place b') #创建标签lb
lb.place(relx = 0.5,rely = 0.5,anchor = CENTER) #使用相对坐标将标签放置到窗口中央
root.mainloop() #进入主事件循环
messagebox模块用于显示一个模式对话框,其中包含一个系统图标、一组按钮和一个简短的特定于应用程序的消息,如状态或错误信息。
messagebox模块大致分为:askokcancel(),askquestion(),askretrycancel(),askyesno(),showerror(),showwarning()
实例代码如下:
import tkinter as tk #导入tkinter模块并命名为tk
from tkinter import messagebox as msgbox #导入tkinter. messagebox模块并命名
#定义各个函数用于相应按钮事件
def btn1_clicked():
msgbox.showinfo("Info", " showinfo测试!")
def btn2_clicked():
msgbox.showwarning("Warning", " showwarning测试!")
def btn3_clicked():
msgbox.showerror("Error", "showerror测试!")
def btn4_clicked():
msgbox.askquestion("Question", "askquestion测试!")
def btn5_clicked():
msgbox.askokcancel("OkCancel", "askokcancel测试!")
def btn6_clicked():
msgbox.askyesno("YesNo", "askyesno测试!")
def btn7_clicked():
msgbox.askretrycancel("Retry", "askretrycancel测试!")
top = tk.Tk() #创建tkinter对象
top.title("MsgBox Test") #设置标题
#创建按钮用于触发各个对话框函数
btn1 = tk.Button(top, text = "showinfo", command = btn1_clicked)
btn1.pack(fill = tk.X)
btn2 = tk.Button(top, text = "showwarning", command = btn2_clicked)
btn2.pack(fill = tk.X)
btn3 = tk.Button(top, text = "showerror", command = btn3_clicked)
btn3.pack(fill = tk.X)
btn4 = tk.Button(top, text = "askquestion", command = btn4_clicked)
btn4.pack(fill = tk.X)
btn5 = tk.Button(top, text = "askokcancel", command = btn5_clicked)
btn5.pack(fill = tk.X)
btn6 = tk.Button(top, text = "askyesno", command = btn6_clicked)
btn6.pack(fill = tk.X)
btn7 = tk.Button(top, text = "askretrycancel", command = btn7_clicked)
btn7.pack(fill = tk.X)
top.mainloop() #进入主事件循环
filedialog模块用于打开文件对话框,该模块提供了2个函数:
askopenfilename()函数用于打开“打开”对话框
asksaveasfilename()函数用于打开“另存为”对话框
以打开为实例代码如下:
import tkinter.filedialog #导入tkinter.filedialog模块
from tkinter import * #导入tkinter模块
root = Tk() #创建tkinter对象
#定义函数用于响应按钮事件
def callback():
fileName = filedialog.askopenfilename() #打开“打开”对话框
print(fileName) #输出文件名
#创建按钮用于触发事件
Button(root,text='打开文件',command=callback).pack()
root.mainloop() #进入主事件循环
输出路径
colorchooser模块用于打开颜色选择对话框,由askcolor()函数实现。
实例代码如下:
import tkinter.colorchooser #导入tkinter.colorchooser模块
from tkinter import * #导入tkinter模块
root = Tk() #创建tkinter对象
#定义函数用于相应按钮事件
def callback():
fileName = colorchooser.askcolor() #打开颜色选择对话框
print(fileName) #输出颜色信息
#创建按钮
Button(root,text="选择颜色",command=callback).pack()
root.mainloop() #进入主事件循环
根据分析,计算器应用程序可分为两大功能模块:
(1)创建计算器界面:计算器界面由多个按钮(如数字按钮、符号按钮等)和一个标签(用于输出按钮信息和计算结果)构成,可利用tkinter提供的Button控件和Label控件实现,再利用布局管理器(grid布局)将各个控件排列显示,其中创建Button控件时利用其command属性调用相应的功能函数。
(2)创建按钮键值类:该类中定义一个构造方法用于接收按钮值,然后定义多个方法用于实现具体的按键功能(供Button控件调用),包括实现添加数值功能的方法,实现删除功能的方法,实现清空功能的方法,实现切换正负号功能的方法,实现添加小数点功能的方法,以及实现计算功能的方法。
import tkinter,time,decimal,math,string #加载各种库
window=tkinter.Tk() #创建tkinter对象
window.title('计算器') #设置标题
window.resizable(0,0) #设置大小不可变
#全局变量,storage存储列表,vartext存储字符串,result存储结果,symbol存储符号
global storage, vartext, result, symbol
result = symbol = None #变量result和symbol设置值为None
vartext = tkinter.StringVar() #创建StringVar对象
storage = [] #变量storage设置为列表
#按键值类
class key_press:
global storage, vartext, result, symbol #引用全局变量
#构造方法,设置按键属性
def __init__(self,anjian):
self.key = anjian #按键名称
#添加,用于将按键值添加到storage列表,再将storage的值设置为vartext的值
def jia(self):
storage.append(self.key) #将按键值添加到storage列表
vartext.set(''.join(storage)) #将storage的值连接生成一个新的字符串,并设置为vartext的值
#删除功能
def retreat(self):
storage.pop() #移除storage列表的值(默认最后一个元素)
vartext.set(''.join(storage)) #将storage的值连接生成一个新的字符串,并设置为vartext的值
#清除功能
def clear(self):
storage.clear() #清空storage列表
vartext.set('') #设置vartext的值为空
result = None #变量result结果改为None
symbol = None #变量symbol结果改为None
#切换正负功能
def plus_minus(self):
if storage[0]: #先判断storage[0]是否有值
if storage[0] == '-': #如果storage[0]值为“-”
storage[0] = '+' #将storage[0]值改为“+”
elif storage[0] == '+': #如果storage[0]值为“+”
storage[0] = '-' #将storage[0]值为“-”
else:
storage.insert(0, '-') #如果storage[0]的值既不是“+”,又不是“-”,则表示没有符号,添加一个“-”
vartext.set(''.join(storage)) #将storage的值连接生成一个新的字符串,并设置为vartext的值
#添加小数点功能
def decimal_point(self):
if storage.count('.') >= 1: #如果已经存在小数点,则什么都不做
pass
else:
if storage == []: #如果storage为空
storage.append('0') #给storage队列添加0
storage.append('.') #给storage队列添加.
vartext.set(''.join(storage)) #将storage的值连接生成一个新的字符串,并设置为vartext的值
#运算
def operation(self):
global storage, vartext, result, symbol #引用全局变量
if vartext.get() == '': #如果vartext中没有值,则什么也不做
pass
else:
get1 = decimal.Decimal(vartext.get()) #获取输入的数值
if self.key in ('1/x','sqrt'): #如果按键值属于'1/x'和'sqrt'其中之一
if self.key == '1/x': #如果按键值是“1/x”
result = 1/get1 #将1/变量get1的结果赋值给变量result
elif self.key == 'sqrt': #如果按键值是“sqrt”
result = math.sqrt(get1) #计算变量get1的平方根
elif self.key in ('+','-','*','/','='): #判断按键值
if symbol is not None: #如果symbol变量不是None
get1 = decimal.Decimal(result) #获取第一次输入的数值
get2 = decimal.Decimal(vartext.get()) #获取第二次输入的数值
if symbol == '+': #如果符号是“+”
result = get1 + get2 #相加
elif symbol == '-': #如果符号是“-”
result = get1 - get2 #相减
elif symbol == '*': #如果符号是“*”
result = get1 * get2 #相乘t
elif symbol == '/': #如果符号是“/”
result = get1 / get2 #相除
else: #如果没有输入符号
result = get1 #获取get1的值
if self.key == '=': #如果输入的键值为“=”
symbol = None #变量symbol则赋值为None
else: #输入的键值不为“=”
symbol = self.key #将输入的键值赋值给symbol
print(symbol) #输出变量symbol,表示符号
print(result) #输出变量result,表示结果
vartext.set(str(result)) #将结果转为字符串形式,并设置为vartext的值
storage.clear() #清空storage列表
#计算器布局
def layout(window):
global storage, vartext, result, symbol #引用全局变量
#设置顶部标签,用于展示按键的值
entry1 = tkinter.Label(window, width=30, height=2, bg='white', anchor='se',\
textvariable=vartext)
entry1.grid(row=0, columnspan=5)
#添加按钮
buttonJ=tkinter.Button(window,text='←',width=5,command=key_press('c').retreat)
buttonCE=tkinter.Button(window,text='',width=5)
buttonC=tkinter.Button(window,text=' C ',width=5,command=key_press('c').clear)
button12=tkinter.Button(window,text='±',width=5,\
command=key_press('c').plus_minus)
buttonD=tkinter.Button(window,text='√',width=5,\
command=key_press('sqrt').operation)
buttonJ.grid(row=2,column=0)
buttonCE.grid(row=2,column=1)
buttonC.grid(row=2,column=2)
button12.grid(row=2,column=3)
buttonD.grid(row=2,column=4)
button7=tkinter.Button(window,text=' 7 ',width=5,command=key_press('7').jia)
button8=tkinter.Button(window,text=' 8 ',width=5,command=key_press('8').jia)
button9=tkinter.Button(window,text=' 9 ',width=5,command=key_press('9').jia)
buttonc=tkinter.Button(window, text=' / ',width=5,command=key_press('/').operation)
buttonf= tkinter.Button(window, text=' ',width=5)
button7.grid(row=3,column=0)
button8.grid(row=3,column=1)
button9.grid(row=3,column=2)
buttonc.grid(row=3,column=3)
buttonf.grid(row=3,column=4)
button4=tkinter.Button(window,text=' 4 ',width=5,command=key_press('4').jia)
button5=tkinter.Button(window,text=' 5 ',width=5,command=key_press('5').jia)
button6=tkinter.Button(window,text=' 6 ',width=5,command=key_press('6').jia)
buttonx=tkinter.Button(window,text=' * ',width=5,command=key_press('*').operation)
buttonfs=tkinter.Button(window,text='1/x',width=5,\
command=key_press('1/x').operation)
button4.grid(row=4,column=0)
button5.grid(row=4,column=1)
button6.grid(row=4,column=2)
buttonx.grid(row=4,column=3)
buttonfs.grid(row=4,column=4)
button1 = tkinter.Button(window, text=' 1 ',width=5,command=key_press('1').jia)
button2 = tkinter.Button(window, text=' 2 ',width=5,command=key_press('2').jia)
button3 = tkinter.Button(window, text=' 3 ',width=5,command=key_press('3').jia)
button_= tkinter.Button(window, text=' - ',width=5,command=key_press('-').operation)
buttondy= tkinter.Button(window, text=' \n = \n ',width=5,\
command=key_press('=').operation)
button1.grid(row=5, column=0)
button2.grid(row=5, column=1)
button3.grid(row=5, column=2)
button_.grid(row=5, column=3)
buttondy.grid(row=5, column=4,rowspan=2)
button0=tkinter.Button(window,text=' 0 ',width=11,command=key_press('0').jia)
buttonjh = tkinter.Button(window,text=' . ',width=5,\
command=key_press('c').decimal_point)
buttonjia=tkinter.Button(window,text=' + ',width=5,\
command=key_press('+').operation)
button0.grid(row=6,column=0,columnspan=2)
buttonjh.grid(row=6,column=2)
buttonjia.grid(row=6,column=3)
layout(window) #window窗口应用layout布局
window.mainloop() #进入事件(消息)循环