Mac下安装Python 3

Mac系统会自带Python 2.7.x。安装Python 3时,不要卸载Python 2.7.x,因为有Mac系统有一些库会依赖于Python 2.7.x。

安装步骤:

1 去Python官网www.python.org 下载最新版的Python 3.x for Mac。

注意,要下载稳定版,目前应该是3.6.4。不要下载alpha版本(内测版)和beta版本(公测版)

 
1.png

2 安装

3 在终端输入python -V检查python2的版本。输入python3 -V检查python3的版本。若正确显示版本号,说明安装成功。

 
2.png

4 用which python和which python3分别查看python2和python3的安装路径

 
3.png

5 至此,既可以使用python2,也可以使用python3。使用方法为:

python test.py
python3 test.py

若碰到包含中文的python程序,可以使用python3来运行。因为编码问题,python2对中文的支持不够方便。

 



实现简单计算器

代码

# 定义函数
def add(x, y):
   """相加"""
   
   return x + y
 
def subtract(x, y):
   """相减"""
 
   return x - y
 
def multiply(x, y):
   """相乘"""
 
   return x * y
 
def divide(x, y):
   """相除"""
 
   return x / y
 
# 用户输入
print("选择运算:")
print("1、相加")
print("2、相减")
print("3、相乘")
print("4、相除")
 
choice = input("输入你的选择(1/2/3/4):")
 
num1 = int(input("输入第一个数字: "))
num2 = int(input("输入第二个数字: "))
 
if choice == '1':
   print(num1,"+",num2,"=", add(num1,num2))
 
elif choice == '2':
   print(num1,"-",num2,"=", subtract(num1,num2))
 
elif choice == '3':
   print(num1,"*",num2,"=", multiply(num1,num2))
 
elif choice == '4':
   print(num1,"/",num2,"=", divide(num1,num2))
else:
   print("非法输入")

运行结果:

选择运算:
1、相加
2、相减
3、相乘
4、相除
输入你的选择(1/2/3/4):3
输入第一个数字: 2
输入第二个数字: 5
2 * 5 = 10


全局变量的引用和修改

一、引用

例1

a = 1

def func():
    if 1 == a:
        print("a = %d" % a)
        
if __name__ == '__main__':
func()

运行结果:

a = 1

二、修改

例2

a = 1

def func():
    a = 2
    print ("in func a:", a)

if __name__ == '__main__':
    print("before func a:", a)
    func()
    print("after func a:", a)

运行结果:

before func a: 1
in func a: 2
after func a: 1

说明:
从程序运行结果可以看出,全局变量a的值,并没有成功被修改为2.
这是因为,func()中的a,是一个局部变量,是在新的内存区域生成的一个新对象,只是名字也叫a罢了。

例3

a = 1

def func():
    global a
    a = 2
    print ("in func a:", a)

if __name__ == '__main__':
    print("before func a:", a)
    func()
    print("after func a:", a)

运行结果:

before func a: 1
in func a: 2
after func a: 2

说明:加了global之后,func中的a就是第一行定义的全局变量a,所以可成功修改值

三、结论

若只是引用全局变量,不需要加global关键字;
若要修改全局变量,需要加global关键字。


join方法和eval方法

一、join方法

语法:
str.join(sequence)

功能:
join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串

参数:
sequence -- 要连接的元素序列

返回值:
返回通过指定字符连接序列中元素后生成的新字符串

例1

str = "-";
seq = ("a", "b", "c"); # 字符串元组
newstr = str.join(seq)
print(newstr)

运行结果:

a-b-c

例2

mylist = ['1', '+', '2', '-', 'c']
res = ''.join(mylist)
print(res)

运行结果:

1+2-c

二、eval方法

语法:
eval(expression, globals=None, locals=None)

功能:
将字符串str当成有效的表达式来求值并返回计算结果。

参数:
expression,要计算的表达式
globals,可选,如果提供了globals参数,那么它必须是dictionary类型
locals,可选,如果提供了locals参数,那么它可以是任意的map对象

返回值:
计算的结果

例3

x = 1
y = 2
z = eval('x + y')
print(z)

运行结果:

3

例4

mylist = ['1', '+', '2', '*', '3']
str = ''.join(mylist)
res = eval(str)
print(res)

运行结果:

7


实现带UI的简易计算器(上)

一、需求

实现一个简易计算器,用户界面类似小米手机的计算器。

 
calculator.png

二、编程环境

语言:Python 3
操作系统:Win/Mac

三、实现过程

(一)界面构成

首先,咱们看一下上面整个页面的构成:
有两个Label,上面那个height较大的Label用来显示计算过程,下面那个height较小的Label用来显示计算结果。
再下面是19个Button,排列成五行四列(等号占了两行)。

(二)数值定义

界面的宽度和高度通常用像素来表示,像素英文为pixel,简写为px。
按纽的宽和高设为70px * 60px,则整个界面的宽度为70px * 4 = 280px。
显示计算过程的Label高设为120px,显示计算结果的Label高设为60px,则整个界面的高度为120 + 60 + 60 * 5 = 480px。

这些数值以及字体、字号、按钮颜色、按纽边框粗细,都可以定义为全局变量:

w = 280                 #整个界面的宽度
h = 480                 #整个界面的高度
processH = 120          #存放计算过程的Label的高度
resultH = 60            #存放计算结果的Label的高度
btnWidth = 70           #按纽宽度
btnHeight = 60          #按纽高度
msfont = '微软雅黑'     #微软雅黑字体
fontSize = 20           #字体大小
btnFgColor = '#4F4F4F'  #按纽颜色
btnBorderWidth = 0.5    #按纽边框粗细

(三)编写整个界面和两个Label

import tkinter #导入tkinter模块


#定义数值
w = 280                 #整个界面的宽度
h = 480                 #整个界面的高度
processH = 120          #存放计算过程的Label的高度
resultH = 60            #存放计算结果的Label的高度
btnWidth = 70           #按纽宽度
btnHeight = 60          #按纽高度
msfont = '微软雅黑'     #微软雅黑字体
fontSize = 20           #字体大小
btnFgColor = '#4F4F4F'  #按纽颜色
btnBorderWidth = 0.5    #按纽边框粗细


#面板设置
root = tkinter.Tk()
root.minsize(w,h)                       #面板大小的最小值
root.title('海天一树的计算器')          #面板的标题

process = tkinter.StringVar()           #字符串用于存放计算过程,初始状态为空
process.set('')
result = tkinter.StringVar()            #字符串用于存放计算结果,初始状态为0
result.set(0)                           

#labelProcess用于显示计算过程,labelResult用于显示计算结果
labelProcess = tkinter.Label(root,font = (msfont,fontSize),bg = '#ff0000',bd ='9',fg = '#828282',anchor = 'se',textvariable = process)
labelProcess.place(width = w,height = processH)
labelResult = tkinter.Label(root,font = (msfont,30),bg = '#00ff00',bd ='9',fg = 'black',anchor = 'se',textvariable = result)
labelResult.place(y = processH,width = w,height = resultH)

运行结果:

 
1.png

说明:
(1)tkinter.Label的数据结构为:

属性名称属性含义
anchor 指示文字会被放在控件的什么位置, 可选项有 N, NE, E, SE, S, SW, W, NW, CENTER. 默认为 CENTER.
aspect 控件的宽高比, 即 width/height , 以百分比形式表示. 默认为 150, 即 Message 控件宽度比其高度大 50%. 注意: 如果显式的指定了控件宽度, 则该属性将被忽略.
background 控件的背景色. 默认值为当前窗口系统的默认背景色.
bg 同 background.
borderwidth 边框宽度. 默认为2.
bd 同 borderwidth.
cursor 定义鼠标移动到 Message 上时的光标样式. 默认为系统标准样式.
font 文字字体. 默认为当前系统默认.
foreground 文字颜色. 默认为当前系统默认.
fg 同 foreground
highlightbackground 和 highlightcolor, highlightthickness 这两个属性一起指定了控件如何绘制高亮区域.
highlightcolor 参考 highlightbackground.
highlightthickness 参考 highlightbackground.
justify 指示多行文本如何对齐. 可选项为 LEFT, RIGHT, CENTER. 默认为 LEFT. 注意: 该属性指示文字对齐方式. 如果要指定文字在控件内的位置, 请使用 anchor 属性.
padx 水平方向的边距. 默认为 -1, 即无边距.
pady 垂直方向的边距. 默认为 -1, 即无边距.
relief 边框样式. 默认为 FLAT. 其他可选项为 SUNKEN, RAISED, GROOVE, RIDGE.
takefocus 如果设置为 True, 控件将可以获取焦点. 默认为 False.
text 文字内容. 控件将根据宽度自动对文字进行断行.
textvariable 关联一个 Tkinter variable 对象, 通常为 StringVar 对象. 控件文本将在该对象改变时跟着改变.
width 控件宽度, 单位为 charater units (不是像素). 如果未指定该选项, 将根据 aspect 属性自动设置宽度.

(2)颜色的RGB表示法
R--Red
G--Green
B--Blue
R, G, B的取值范围为0x000xff,对应于十进制的0255

下表列举了几个常见的RGB值所对应的颜色

RGB值颜色
#ff0000 红色
#00ff00 绿色
#0000ff 蓝色
#ffff00 黄色
#ff00ff 粉色
#00ffff 浅蓝色
#000000 黑色
#ffffff 白色
#555555 深灰色
#cccccc 浅灰色

(四)添加数字按纽

#数字按键
btn7 = tkinter.Button(root,text = '7',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('7'))
btn7.place(x = 0,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btn8 = tkinter.Button(root,text = '8',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('8'))
btn8.place(x = btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btn9 = tkinter.Button(root,text = '9',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('9'))
btn9.place(x = 2 * btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)

btn4 = tkinter.Button(root,text = '4',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('4'))
btn4.place(x = 0,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btn5 = tkinter.Button(root,text = '5',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('5'))
btn5.place(x = btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btn6 = tkinter.Button(root,text = '6',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('6'))
btn6.place(x = 2 * btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)

btn1 = tkinter.Button(root,text = '1',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('1'))
btn1.place(x = 0,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn2 = tkinter.Button(root,text = '2',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('2'))
btn2.place(x = btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn3 = tkinter.Button(root,text = '3',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('3'))
btn3.place(x = 2 * btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn0 = tkinter.Button(root,text = '0',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('0'))
btn0.place(x = btnWidth,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)

运行结果:

 
2.png

说明:
(1)Button按纽属性

属性描述
text 显示按纽内容
command 指定Button的事件处理函数
compound 指定文本与图像的位置关系
bitmap 指定位图
focus_set 设置当前组件得到的焦点
master 代表了父窗口
bg 设置背景颜色
fg 设置前景颜色
font 设置字体大小
height 设置显示高度、如果未设置此项,其大小以适应内容标签
relief 指定外观装饰边界附近的标签,默认是平的,可以设置的参数有flat、groove、raised、ridge、solid、sunken
width 设置显示宽度,如果未设置此项,其大小以适应内容标签
wraplength 将此选项设置为所需的数量限制每行的字符,数默认为0
state 设置组件状态;正常(normal),激活(active),禁用(disabled)
anchor 设置Button文本在控件上的显示位置,可取值:n(north),s(south),w(west),e(east),和ne,nw,se,sw
bd 设置Button的边框大小;bd(bordwidth)缺省为1或2个像素

(2)如果是在Mac下,上面的代码显示效果为

 
3.png

如果对按钮添加参数highlightbackgound='#cccccc',则显示效果为

 
4.png

这样倒是将按纽的整个边框都显示出来了,但是看起来怪怪的。这是因为tkinter对Mac系统支持得不好,有些属性不起作用的缘故。

(五)添加符号按纽

btnac = tkinter.Button(root,text = 'AC',bd = btnBorderWidth,font = ('黑体',fontSize),fg = 'orange',command = lambda :clickSign('AC'))
btnac.place(x = 0,y = processH + resultH,width = btnWidth,height = btnHeight)
btnback = tkinter.Button(root,text = '←',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('b'))
btnback.place(x = btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btndiv = tkinter.Button(root,text = '÷',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('/'))
btndiv.place(x = 2 * btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btnmul = tkinter.Button(root,text ='×',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('*'))
btnmul.place(x = 3 * btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btnsub = tkinter.Button(root,text = '-',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickSign('-'))
btnsub.place(x = 3 * btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btnadd = tkinter.Button(root,text = '+',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickSign('+'))
btnadd.place(x = 3 * btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btnequ = tkinter.Button(root,text = '=',bg = 'orange',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda :clickEqual())
btnequ.place(x = 3 * btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = 2 * btnHeight)
btnper = tkinter.Button(root,text = '%',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickPer())
btnper.place(x = 0,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)
btnpoint = tkinter.Button(root,text = '.',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickNum('.'))
btnpoint.place(x = 2 * btnWidth,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)

运行结果:

 
5.png

到这一步,界面都已经绘制完了。下一步要开始做功能。

(六)实现点击数字按钮的功能

lists = []                                    #数组,保存数字和运算符
isSignClicked = False               #是否点击了符号按纽
isEqualClicked = False              #是否点击了等号按纽

def clickNum(num):                   
    global isSignClicked            #将isSignClicked变量设为全局变量
    global isEqualClicked
    
    if True == isSignClicked:                   
        result.set(0)               #如果上次按过运算符,那么这次要把原先的数字清空,否则会加在上次那个数的末尾
        isSignClicked = False

    if True == isEqualClicked:
        result.set(0)
        isEqualClicked = False
    
    #判断界面的数字是否为0
    oldnum = result.get()      
    if '0' == oldnum:               #如果界面上数字为0 则获取按下的数字
        if '.' == num:
            num = '0.'
        result.set(num)
    else:
        if '.' in oldnum and '.' == num:  #如果之前已经输入过'.',那么再输入'.'不会有反应
            pass 
        else:   
            newnum = oldnum + num
            result.set(newnum)          #将按下的数字写到面板中

运行结果:

 
6.png

这里的global关键字,可以参考
小朋友学Python(27):全局变量的引用和修改

(七)实现点击符号(百分号和等号除外)按纽的功能

#点击运算符号(等号除外)
def clickSign(sign):
    global lists
    global isSignClicked
    
    num = result.get()              #获取界面数字
    if 0 == num.find('='):          #在连续计算时,若得到的是“=15”,要去掉等号,取其数字
        num = num[1:len(num)]
    lists.append(num)               #将界面获取的数字保存列表中

    lists.append(sign)              #将运算符号保存到列表中
    isSignClicked = True

    if 'AC' ==  sign:               #如果按下的是'AC'按键,则清空列表内容,并将屏幕上的数字设置为默认值0
        lists.clear()
        process.set('')
        result.set(0)
    if 'b' ==  sign:                #如果按下的是退格按纽,则选取当前数字第一位到倒数第二位
        a = num[0:-1]
        lists.clear()
        result.set(a)
        if 0 == len(a):             #如果是最后一个数,退格后变成0
            result.set(0)

(八)实现点击“%”的功能

#求百分值
def clickPer():
    curval = result.get()
    lists.append(curval)
    lists.append('/')
    lists.append('100')
    res = ''.join(lists)
    res = eval(res)
    result.set(res)
    lists.clear()

这里的join函数和eval函数,可以参考
小朋友学Python(28):join方法和eval方法

(九)实现点击“=”的功能

#获取运算结果
def clickEqual():
    global lists
    global isEqualClicked

    isEqualClicked = True
    curval = result.get()           #将界面上的数字添加到列表中
    # 2*=4, 4*=16, 16*=256, 如果按了*=之前,有等号的话,要把等号去掉
    if True == isSignClicked and 0 == curval.find('='): 
        curval = curval[1:len(curval)]
    lists.append(curval)

    proc = ''.join(lists)           #将列表内容用join命令将字符串链接起来
    res = eval(proc)                #用eval命令运算字符串中的内容
    res = '='+str(res)              #给运算结果前添加一个 ‘=’ 显示 
    res = res[0:10]                 #所有的运算结果取9位数
    
    process.set(proc)               #显示运算过程
    result.set(res)                 #显示运算结果

    lists.clear()                   #清空lists数组中的内容

运行结果:

 
7.png

(十)调整两个Label的颜色

过程Label和结果Label的背景色很不好看,将两个Label的背景色都调为:
bg = ‘#EEE9E9’

运行效果:

 


实现带UI的简易计算器(下)

一、最终效果

 
8.png

二、完整程序

import tkinter #导入tkinter模块


#定义数值
w = 280                 #整个界面的宽度
h = 480                 #整个界面的高度
processH = 120          #存放计算过程的Label的高度
resultH = 60            #存放计算结果的Label的高度
btnWidth = 70           #按纽宽度
btnHeight = 60          #按纽高度
msfont = '微软雅黑'     #微软雅黑字体
fontSize = 20           #字体大小
btnFgColor = '#4F4F4F'  #按纽颜色
btnBorderWidth = 0.5    #按纽边框粗细


#面板设置
root = tkinter.Tk()
root.minsize(w,h)                       #面板大小的最小值
root.title('海天一树的计算器')          #面板的标题

process = tkinter.StringVar()           #字符串用于存放计算过程,初始状态为空
process.set('')
result = tkinter.StringVar()            #字符串用于存放计算结果,初始状态为0
result.set(0)                           

#labelProcess用于显示计算过程,labelResult用于显示计算结果
labelProcess = tkinter.Label(root,font = (msfont,fontSize),bg = '#EEE9E9',bd ='9',fg = '#828282',anchor = 'se',textvariable = process)
labelProcess.place(width = w,height = processH)
labelResult = tkinter.Label(root,font = (msfont,30),bg = '#EEE9E9',bd ='9',fg = 'black',anchor = 'se',textvariable = result)
labelResult.place(y = processH,width = w,height = resultH)

#数字按键
btn7 = tkinter.Button(root,text = '7',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('7'))
btn7.place(x = 0,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btn8 = tkinter.Button(root,text = '8',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('8'))
btn8.place(x = btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btn9 = tkinter.Button(root,text = '9',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('9'))
btn9.place(x = 2 * btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)

btn4 = tkinter.Button(root,text = '4',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('4'))
btn4.place(x = 0,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btn5 = tkinter.Button(root,text = '5',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('5'))
btn5.place(x = btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btn6 = tkinter.Button(root,text = '6',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('6'))
btn6.place(x = 2 * btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)

btn1 = tkinter.Button(root,text = '1',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('1'))
btn1.place(x = 0,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn2 = tkinter.Button(root,text = '2',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('2'))
btn2.place(x = btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn3 = tkinter.Button(root,text = '3',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('3'))
btn3.place(x = 2 * btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = btnHeight)
btn0 = tkinter.Button(root,text = '0',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda : clickNum('0'))
btn0.place(x = btnWidth,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)

#运算符号按键
btnac = tkinter.Button(root,text = 'AC',bd = btnBorderWidth,font = ('黑体',fontSize),fg = 'orange',command = lambda :clickSign('AC'))
btnac.place(x = 0,y = processH + resultH,width = btnWidth,height = btnHeight)
btnback = tkinter.Button(root,text = '←',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('b'))
btnback.place(x = btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btndiv = tkinter.Button(root,text = '÷',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('/'))
btndiv.place(x = 2 * btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btnmul = tkinter.Button(root,text ='×',font = (msfont,fontSize),fg = btnFgColor,bd = btnBorderWidth,command = lambda:clickSign('*'))
btnmul.place(x = 3 * btnWidth,y = processH + resultH,width = btnWidth,height = btnHeight)
btnsub = tkinter.Button(root,text = '-',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickSign('-'))
btnsub.place(x = 3 * btnWidth,y = processH + resultH + btnHeight,width = btnWidth,height = btnHeight)
btnadd = tkinter.Button(root,text = '+',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickSign('+'))
btnadd.place(x = 3 * btnWidth,y = processH + resultH + 2 * btnHeight,width = btnWidth,height = btnHeight)
btnequ = tkinter.Button(root,text = '=',bg = 'orange',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda :clickEqual())
btnequ.place(x = 3 * btnWidth,y = processH + resultH + 3 * btnHeight,width = btnWidth,height = 2 * btnHeight)
btnper = tkinter.Button(root,text = '%',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickPer())
btnper.place(x = 0,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)
btnpoint = tkinter.Button(root,text = '.',font = (msfont,fontSize),fg = (btnFgColor),bd = btnBorderWidth,command = lambda:clickNum('.'))
btnpoint.place(x = 2 * btnWidth,y = processH + resultH + 4 * btnHeight,width = btnWidth,height = btnHeight)


#点击数字
lists = []                          #数组,保存数字和运算符
isSignClicked = False               #是否点击了符号按纽
isEqualClicked = False              #是否点击了等号按纽

def clickNum(num):                   
    global isSignClicked            #将isSignClicked变量设为全局变量
    global isEqualClicked
    
    if True == isSignClicked:                   
        result.set(0)               #如果上次按过运算符,那么这次要把原先的数字清空,否则会加在上次那个数的末尾
        isSignClicked = False

    if True == isEqualClicked:
        result.set(0)
        isEqualClicked = False
    
    #判断界面的数字是否为0
    oldnum = result.get()      
    if '0' == oldnum:               #如果界面上数字为0 则获取按下的数字
        if '.' == num:
            num = '0.'
        result.set(num)
    else:
        if '.' in oldnum and '.' == num:  #如果之前已经输入过'.',那么再输入'.'不会有反应
            pass 
        else:   
            newnum = oldnum + num
            result.set(newnum)          #将按下的数字写到面板中


#点击运算符号(等号除外)
def clickSign(sign):
    global lists
    global isSignClicked
    
    num = result.get()              #获取界面数字
    if 0 == num.find('='):          #在连续计算时,若得到的是“=15”,要去掉等号,取其数字
        num = num[1:len(num)]
    lists.append(num)               #将界面获取的数字保存列表中

    lists.append(sign)              #将运算符号保存到列表中
    isSignClicked = True

    if 'AC' ==  sign:               #如果按下的是'AC'按键,则清空列表内容,并将屏幕上的数字设置为默认值0
        lists.clear()
        process.set('')
        result.set(0)
    if 'b' ==  sign:                #如果按下的是退格按纽,则选取当前数字第一位到倒数第二位
        a = num[0:-1]
        lists.clear()
        result.set(a)
        if 0 == len(a):             #如果是最后一个数,退格后变成0
            result.set(0)

            
#求百分值
def clickPer():
    curval = result.get()
    lists.append(curval)
    lists.append('/')
    lists.append('100')
    
    res = ''.join(lists)
    res = eval(res)
    result.set(res)
    
    lists.clear()
        

#获取运算结果
def clickEqual():
    global lists
    global isEqualClicked

    isEqualClicked = True
    curval = result.get()           #将界面上的数字添加到列表中
    # 2*=4, 4*=16, 16*=256, 如果按了*=之前,有等号的话,要把等号去掉
    if True == isSignClicked and 0 == curval.find('='): 
        curval = curval[1:len(curval)]
    lists.append(curval)

    proc = ''.join(lists)           #将列表内容用join命令将字符串链接起来
    res = eval(proc)                #用eval命令运算字符串中的内容
    res = '='+str(res)              #给运算结果前添加一个 ‘=’ 显示 
    res = res[0:10]                 #所有的运算结果取9位数
    
    process.set(proc)               #显示运算过程
    result.set(res)                 #显示运算结果

    lists.clear()                   #清空lists数组中的内容


root.mainloop()

三、Github源码下载

https://github.com/zhenghaishu/Calculator-Python

 

 

posted on 2018-09-08 00:03  Alan_Fire  阅读(633)  评论(0编辑  收藏  举报