当前位置:首页 » tkinter » 正文

用tkinter做一个界面漂亮的计算器

计算器界面及美化按钮图片

到目前为止,我前面的文章已经讲解了标签,按钮,Entry单行文本框3个组件,以及pack,grid,place  3个布局定位方法。学了这些基本知识,我们就可以做一些很小的软件应用,今天我就用学的这一点知识,参考window自带的计算器,做一个计算器软件。我的做的成品运行结果如下:

1.PNG

1. 显示区是2个标签,最上面的标签1来用显示上一次算式和结果。

   下面的标签2用来显示当次输入算式及结果。

   2个标签外的框是用图片做的美化。图片1如下:

      beijin.png 图片1

2. 按钮区19个按钮,也都用图片做了美化,退格键,数字0键 ,及其它键位的图片分别是图片2,图片3,图片4:

       图片2     图片3      图片4

3. 窗体背景颜色及标签字体颜色等,都是用取色器软件在win7 或 win10计算器软件取色所得的16进制颜色,如窗体背景色是'#D9E4F1'  ,请注意,使用16进制也要加上引号。

计算器设计思路:

1. 整个窗体布局用grid(),分成6行4列。

  在 表格框(0,0)里,创建一个框架fr1,框架里,先用place()方法居中布局标签1,用来用显示图片1,即2个标签的外框图;然后用pack()布局2个标签,从上到下分别是标签1和标签2。

   说明:同一个父组件下,grid和pack不要混用,但同一个父组件下,place可以跟另外2个布局方法混用。

2. 所有按钮都用图片美化,关于自定义美化按钮,在按钮的文章有讲解,大家可以回看一下。我总结了一下,按钮要用图片定义来做,参数必须要: 

   relief='flat',   bd=0,bg=root['bg'],   activebackground=root['bg']                           丶丌皛

  即,样式平整,按钮外框宽度为0,按钮背景色跟窗体颜色一致(也可以按钮边缘色是透明的),按钮活动背景色跟窗体颜色一致。

3. 点击退格键:删除前面输入的一个字符,方法:字符串[:-1]

  点击“=”键:用python的eval()来计算,用try语句,如果不出错,就输出正确结果,否则,算式有误,就用except输出:算式=error (在输入算式时,我没有写验证代码,大家有兴趣,自行写吧)

  点击“C”键 :用来清除算式及上次历史记录。

  点击其它键,用来输出算式,如果每个按钮都写一个command=相关的函数,那太繁琐了,我用lambda匿名函数来简化。(关于匿名函数,python基本知识你一定学过,我在按钮文章里也有说明,大家可以回看一下)

4.  其它:

1:软件的标题栏的计算器图标,请自行准备。

2:加入图片后,运行程序,加载图片慢,我的电脑运行有点闪,我在软件运行前,用 root.withdraw()   隐藏窗体,最后,等图片都加载好,就用 root.deiconify() 显示窗体。

3:禁止手动调整窗体尺寸:root.resizable(False,False)

4:电脑编程的%符号是求余操作,这跟window自带的计算器上的%的用法有区别,我也没有仔细研究了解计算器上的%用法,就让eval(算式)函数来处理了。

tkinter计算器完整代码

from tkinter import *
 
def show(cs):               # 点击按钮输入,并显示在标签2
    la2_txt = suanshi.get()     # 由标签2绑定变量获取到点击按钮前的显示内容
    suanshi.set(la2_txt + cs)   # 再根据传来的参数cs重新设置变量的值(即算式)
    # 注意,这里我没有多花心写验证算式的正确性,有兴趣的朋友自行加上
 
def ji_suan ():                                   # 计算,标签2显示结果,算式移到标签1
    try: # 算法正确的话,就在try里输出正确的结果
        result = eval(suanshi.get())                     # 用eval方法来计算变量传来的算式
        la1['text']=suanshi.get() + '=' + str(result)    # 标签1显示算式及结果
        suanshi.set(str(result))                         # 标签2只显示结果
        # 注意,由于绑定了变量,la2.config(text=str(result)) 
        # 或  la2['text']=str(result) 都不可以
    except: # 算式不正确就输入=error
        la1['text']=suanshi.get() + '=error'    # 标签1显示算式及结果
        suanshi.set('')                         # 标签2只显示结果
 
def backspace():                      # 删除前面输入的1个字符
    suanshi.set(str(suanshi.get()[:-1]))      # 这句代码不懂的话就要去复习一下python基本知识了
 
def clear():                      # 显示区的2个标签,恢复到初始状态
    suanshi.set("")               # 标签2显示为0
    la1['text']=''                # 标签1清空 源码来自wb98.com
 
root = Tk()
root.withdraw()  # 窗体暂时隐藏一下
root.title("计算器")         # 设置窗体标题
root.iconbitmap('jsq.ico')   # 设置标题栏图标
root['bg']='#D9E4F1'         # 设置窗体背景色,颜色16进制值可以用取色器软件来获取
root.resizable(False,False)  # 设置窗体不可能手动调整尺寸
 
suanshi=StringVar()   # 设置算式变量suanshi为字符串变量
suanshi.set("")         # 设置初值为0
 
fr1=Frame(root,background='#D9E4F1') # 框架1用来包含标签1和标签2
fr1.grid(row=0,column=0,columnspan=4,sticky=W+E)  # 框架1定位在表格框(0,0)
 
img1=PhotoImage(file='beijin.png')  # 显示区的背景图片
la0=Label(fr1,image=img1,bd=0)    # 图片用标签0来显示
la0.place(relx=0.5,rely=0.5,anchor='center')   # place定位方法显威力了,在fr1里居中显示,就正好做显示区的背景图片
 
# 下面la1和la2代码里 width=17 用来固定标签的宽度,防止字符过多,标签变大,让窗体也跟着变宽,整个窗体布局都乱了
la1=Label(fr1,width=17,font=('黑体',12),foreground='lightslategrey',background='#EEF2FD',anchor=E) # 标签1来用显示上一次算式和结果
la1.pack(fill=X,padx=15,pady=(10,2))  # 横向填充满
 
la2=Label(fr1,width=17,font=('黑体',19),anchor=E,background='#EEF2FD',textvariable=suanshi) # 文本显示靠左,文本显示绑定变量suanshi
la2.pack(fill=X,padx=15 ,pady=(2,10))  # 横向填充满,标签2上加2像素下加5个像素
 
# 各按钮创建,定位:
img2=PhotoImage(file='an.png')   # 按钮图片3
img3=PhotoImage(file='an2.png')  # 0键按钮图片4
img4=PhotoImage(file='an3.png')  # 退格按钮图片2
 
# 下面代码 image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'] 来用自定义图片来美化按钮。
clearButton = Button(root,text="C",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=clear)\
    .grid(row=1,column=0,padx=(10,0))  # padx=(10,0)用于调整跟窗体左边缘的间距,\是代码分行的连接符号,下同
Button(root,image=img4,relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=backspace)\
    .grid(row=1,column=1) # 退格,用于消除前一个字符
Button(root,text="%",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("%"))\
    .grid(row=1,column=2)  # 注意:%在编程里的意思是求余数,这跟计算器里的百分比有区别
Button(root,text="/",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("/"))\
    .grid(row=1,column=3,padx=(0,10))  # 除,padx=(0,10),用于调整跟窗体右边缘的间距,下同
 
Button(root,text="7",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("7"))\
    .grid(row=2,column=0,padx=(10,0))
Button(root,text="8",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("8"))\
    .grid(row=2,column=1)
Button(root,text="9",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("9"))\
    .grid(row=2,column=2)
Button(root,text="*",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("*"))\
    .grid(row=2,column=3,padx=(0,10))
 
Button(root,text="4",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("4"))\
    .grid(row=3,column=0,padx=(10,0))
Button(root,text="5",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("5"))\
    .grid(row=3,column=1)
Button(root,text="6",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("6"))\
    .grid(row=3,column=2)
Button(root,text="-",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("-"))\
    .grid(row=3,column=3,padx=(0,10))  # 减
 
Button(root,text="1",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("1"))\
    .grid(row=4,column=0,padx=(10,0))
Button(root,text="2",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("2"))\
    .grid(row=4,column=1)
Button(root,text="3",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("3"))\
    .grid(row=4,column=2)
Button(root,text="+",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("+"))\
    .grid(row=4,column=3,padx=(0,10))
 
Button(root,text="0",image=img3,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("0"))\
    .grid(row=5,column=0,columnspan=2,sticky=W+E,padx=(10,0),pady=(0,10))  # pady=(0,10)用于调整跟窗体底边的间距,下同。
Button(root,text=".",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:show("."))\
    .grid(row=5,column=2,pady=(0,10))
Button(root,text="=",image=img2,compound='center',relief='flat',bd=0,bg=root['bg'],activebackground=root['bg'],font=('黑体',24),command=lambda:ji_suan())\
    .grid(row=5,column=3,padx=(0,10),pady=(0,10))  # 等于按钮,绑定计算函数
 
root.deiconify()  # 窗体再次显示
 
root.mainloop()


 代码都有注释来讲解,牵涉的知识在以前的文章都有讲解,不懂的请回看以前的文章,我的网站 wb98.com

 下一篇文章,我用tkinter写一个温度转换程序:华氏度转摄氏度,主要是借这个程序来温习和巩固我们才学不久的变量知识。


来源:济亨网

本文链接:http://wb98.com/post/306.html

    << 上一篇 下一篇 >>

    湘公网安备 43011102000514号 - 湘ICP备08100508号