基于python的GUI编程

文章目录

  • 前言
  • 一、 tkinter和Python编程
  • 二、tkinter的使用
    • 创建一个GUI应用程序需要以下5个主要步骤。
  • 三、tkinter常用控件
    • 1,窗口
    • 2,窗口也称为框架(Frame),是屏幕上的一块矩形区域,多用来作为容器布局窗体。
    • 3,Label控件
    • 4,Button控件
    • 5,Entry控件
    • 6,Radiobutton和Checkbutton控件
    • 7,Menu控件
  • 四、事件绑定
    • 1,事件序列
    • 2,事件对象
  • 五、布局管理器
    • 1,pack布局
    • 11.4.2 grid布局
    • 11.4.3 place布局
  • 六、 标准对话框
    • 1,messagebox模块
    • 2, filedialog模块
    • 3, colorchooser模块
  • 总结:编写典型案例计算器实现运算功能
    • 例:编写计算器应用程序,实现简单的算术运算功能。


前言

到目前为止,我们所编写的Python代码都是处于一个文字交互界面的状态。但在实际应用中,很多用户都是非专业的,他们希望所提供的软件能有一个友好的界面,这就用到GUI编程了。
GUI(Graphical User Interface)又称图形用户界面,是指采用图形方式显示的用户操作界面。Python的GUI工具包有很多,其中最常用的有tkinter,wxPython,PyGTK,PyQt等,本章将介绍如何使用tkinter来编写GUI程序。


一、 tkinter和Python编程

tkinter是Python的标准GUI库。
tkinter的优点是简单易用,与Python结合度好。
tkinter在Python 3.x下默认集成,不需要额外安装。因此,想要使用tkinter进行GUI编程,可直接使用import语句导入tkinter模块。
import tkinter

二、tkinter的使用

创建一个GUI应用程序需要以下5个主要步骤。

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()					#进入主事件循环

三、tkinter常用控件

1,窗口

1,在GUI编程中,顶层窗口对象包含组成GUI应用程序的所有小窗口对象,它们可能是文字标签、按钮、列表框等,这些独立的GUI组件称为控件。
基于python的GUI编程_第1张图片

2,窗口也称为框架(Frame),是屏幕上的一块矩形区域,多用来作为容器布局窗体。

窗口中可包含标签、菜单、按钮等其他控件,其运行之后可移动和缩放。
基于python的GUI编程_第2张图片

例:创建一个300×200的窗口,其标题为“金企鹅”,运行后该窗口宽不可变,高可变。

import tkinter						#导入tkinter库
window = tkinter.Tk()					#创建tkinter对象
window.title("金企鹅")					#设置标题
window.geometry("300x200")				#设置窗口大小,注意是字母x
window.resizable(width=False, height=True)		#宽不可变,高可变,默认为True
window.mainloop()					#进入主事件循环

3,Label控件

Label控件是用于在界面上输出描述信息的标签,可以显示文本和图像。
基于python的GUI编程_第3张图片
例:创建一个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()			#进入主事件循环

4,Button控件

通过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()					#进入主事件循环

5,Entry控件

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()			#进入主事件循环

6,Radiobutton和Checkbutton控件

Radiobutton和Checkbutton控件分别用于实现选项的单选和复选功能。
基于python的GUI编程_第4张图片
基于python的GUI编程_第5张图片
例:编写程序,实现通过单选框和复选框设置文字样式的功能。

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()创建与特定控件关联的整型变量。

7,Menu控件

tkinter提供了Menu控件,用于实现顶级菜单、下拉菜单和弹出菜单。
基于python的GUI编程_第6张图片
创建一个顶级菜单,需要先创建一个菜单实例,然后使用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()					#进入主事件循环

1,事件序列

tkinter使用一种称为事件序列的机制来允许用户定义事件,事件序列以字符串的形式表示,其语法格式如下:
modifier-type-detail
说明:
(1)事件序列必须用尖括号括起来;
(2)type字段是最重要的,它通常用于描述事件类型,如鼠标单击、键盘输入等;
(3)modifier字段是可选的,它通常用于描述组合键,如Ctrl、Shift等;
(4)detail字段也是可选的,它通常用于描述具体的按键,如Button-1表示单击鼠标左键。

type字段常用的关键字及含义:
基于python的GUI编程_第7张图片
modifier字段常用的关键字及含义
基于python的GUI编程_第8张图片

2,事件对象

当tkinter调用预先定义的函数时,会将事件对象(作为参数)传递给函数,事件对象的属性及含义如下表所示。
基于python的GUI编程_第9张图片
例:事件绑定实例。

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()

五、布局管理器

1,pack布局

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布局的常用属性:

基于python的GUI编程_第10张图片
(提示)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()

11.4.2 grid布局

grid布局又称为网格布局,是tkinter布局管理器中最灵活多变的布局方法。由于大多数程序界面都是矩形的,我们可以将它划分为由行和列组成的网格,然后根据行号和列号,将控件放置于网格之中。
属性如下:
基于python的GUI编程_第11张图片
例: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()		#进入主事件循环

11.4.3 place布局

place布局使用控件坐标来放置控件的位置。
属性如下:
基于python的GUI编程_第12张图片
例: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()					#进入主事件循环

六、 标准对话框

1,messagebox模块

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()					#进入主事件循环

2, filedialog模块

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()				#进入主事件循环

输出路径

3, colorchooser模块

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()				#进入事件(消息)循环

你可能感兴趣的:(pyhon基础笔记,python,gui,编程语言)