下列实现代码说明:
  下列代码主要是实现计算器功能。由于之前在莫凡老师开设的《用 python 和 tkinter 做简单的窗口视窗》课程当中学习了tkinter的内容,在该课程的结束部分是老师带着做一个关于
登录窗口的小程序。
  在学习了该课程后,自己又去学习了计算器编写的代码,而后,想着能否把这两个小项目结合寄来,于是,新的一个小项目又诞生了。
  该程序的功能是在打开计算器程序之前需要进行一个登陆操作。
  该项目涉及到的前面的project如下:

  1、class13and14and15_登录窗口 - JY小脚丫 - 博客园

    https://www.cnblogs.com/jyfootprint/p/9571509.html

  2、project1_calculator(使用tkinter实现python计算器,含有具体过程与注释) - JY小脚丫 - 博客园

    https://www.cnblogs.com/jyfootprint/p/9570951.html

代码如下:


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# ------------------------------------------------------------
import calculator import tkinter as tk
from tkinter import messagebox
import pickle window = tk.Tk()
window.title("登录窗口")
window.maxsize(460, 300)
window.minsize(460, 300)
# welcom image
canvas = tk.Canvas(window, width=500, height=200)
image_file = tk.PhotoImage(file='my_login.gif')
# 10, 0 表示锚点的横,纵位置; anchor='nw'表示锚点的位置是左上角
image = canvas.create_image(10, 0, anchor='nw', image=image_file)
canvas.pack(side='top') tk.Label(window, text='username:', font=('黑体', 12)).place(x=60, y=160, anchor='nw')
tk.Label(window, text='password:', font=('黑体', 12)).place(x=60, y=190, anchor='nw') # 设置存储的变量
username = tk.StringVar()
password = tk.StringVar()
# 设置登录的输入框,并获取信息
entry_username = tk.Entry(window, textvariable=username, width=30).place(x=150, y=160, anchor='nw')
entry_password = tk.Entry(window, textvariable=password, width=30, show='*').place(x=150, y=190, anchor='nw')
# 初始化 username 的信息
username.set('example@python.com') def usr_login():
usr_name = username.get()
usr_password = password.get()
try:
with open('usrs_info.pickle', 'rb') as usr_file:
usrs_info = pickle.load(usr_file)
except FileNotFoundError:
usrs_info = {'admin': 'admin'}
pickle.dump(usrs_info, usr_file) if usr_name in usrs_info:
if usr_password == usrs_info[usr_name]:
messagebox.showinfo(title='Welcom', message='Welcome to log in! \n'+ usr_name)
window.destroy()
calculator.Calculator()
else:
messagebox.showerror(title='Error', message='Password Error!\nTry again!!')
else:
is_sign_up = messagebox.askyesno(title='Ask', message='You have not sign up yet.\nSign up now?')
if is_sign_up is True:
usr_sign_up() def usr_sign_up():
# 设置窗口
window_sign_up = tk.Toplevel(window)
window_sign_up.title('Sign up window')
window_sign_up.maxsize(460, 180)
window_sign_up.minsize(460, 180) # 设置标签
tk.Label(window_sign_up, text='username:', font=('黑体', 12)).place(x=30, y=30, anchor='nw')
tk.Label(window_sign_up, text='password:', font=('黑体', 12)).place(x=30, y=60, anchor='nw')
tk.Label(window_sign_up, text='confirm password:', font=('黑体', 12)).place(x=30, y=90, anchor='nw') # 设置输入框
# 设置存储的变量
usr_username = tk.StringVar()
usr_password1 = tk.StringVar()
usr_password2 = tk.StringVar()
# 设置登录的输入框,并获取信息
usr_entry_username = tk.Entry(window_sign_up, textvariable=usr_username, width=40).place(x=170, y=30, anchor='nw')
usr_entry_password1 = tk.Entry(window_sign_up, textvariable=usr_password1, width=40, show='*').place(x=170, y=60, anchor='nw')
usr_entry_password2 = tk.Entry(window_sign_up, textvariable=usr_password2, width=40, show='*').place(x=170, y=90, anchor='nw')
# 初始化 username 的信息
usr_username.set('example@python.com')
def new_sign_up():
new_name = usr_username.get()
new_password = usr_password1.get()
new_password_confirm = usr_password2.get()
# 打开配置文件,查看注册的信息是否在文件中
with open('usrs_info.pickle', 'rb') as usr_file:
exist_usr_info = pickle.load(usr_file)
# 对比用户名是否已经储存在文件中
if new_name in exist_usr_info :
messagebox.showerror(title='Error',message='The user has already signed up!') else:
if new_password != new_password_confirm:
messagebox.showerror(title='Error', message='Password and confirm password must be the same!')
else:
exist_usr_info[new_name] = new_password
with open('usrs_info.pickle', 'wb') as usr_file:
# 写入到文件中
pickle.dump(exist_usr_info, usr_file)
messagebox.showinfo(title='Welcome', message='You have successfully signed up!')
window_sign_up.destroy() # 设置注册的按钮
tk.Button(window_sign_up, text='sign up', command=new_sign_up).place(x=220, y=120, anchor='nw') tk.Button(text='login', command=usr_login).place(x=170, y=220, anchor='nw')
tk.Button(text='sign up', command=usr_sign_up).place(x=240, y=220, anchor='nw') window.mainloop()

  



上面代码说明:

语句:  import calculator 
说明:  calculator 是一个自己编写的一个名称为“calculator.py"文件,是用来实现计算器计算功能程序,该程序的内容见一下转接链接
代码内容如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# ------------------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
'''
# ------------------------------------------------------------
# # 7、(完成全部设计)实现基本的计算器功能,补充错误检测, 修改‘C’为清楚功能, '<=='为后退功能
# # # 改动位置位置: def click_button(self, event):
# ------------------------------------------------------------
''' class Calculator:
import tkinter as tk
import tkinter.messagebox as mbox def __init__(self):
# 生成一个窗口对象
self.window = self.tk.Tk()
# 命名窗口对象的显示title
self.window.title('计算器')
# 设置窗口的大小 minsize最小 maxsize最大
self.window.minsize(240, 290)
self.window.maxsize(240, 290)
# 是否清空显示框判定参数
# 设置菜单
self.set_menu()
# 设置显示框
self.label_show = self.tk.Label(text='', anchor='se', font=('黑体', 30), fg='black')
self.label_show.place(x=0, y=0, width=240,height=80)
# 设置按钮组件
self.set_buttons()
# 将窗口放入主消息队列
self.window.mainloop() def set_menu(self):
'''
设置菜单
:return: None
'''
# 创建总菜单
menubar = self.tk.Menu(self.window)
# 创建一个下拉菜单,并且加入文件菜单
filemenu = self.tk.Menu(menubar, tearoff=False)
# 创建菜单中的选项
filemenu.add_command(label='退出计算器', command=self.window.quit ) # print author的函数
def show_author():
self.mbox.showinfo(title='作者信息',message='作者:许建荣\n联系邮箱:jyfootprint@foxmail.com') filemenu.add_command(label='作者信息', command=show_author)
# 将文件菜单作为下拉菜单添加到总菜单中,并且将命名为操作
menubar.add_cascade(label='查看', menu=filemenu)
# 显示总菜单
self.window.config(menu=menubar) def set_buttons(self):
# 基础坐标, x0, y0,开始坐标; x_width, y_width 间隔
x0, y0, x_width, y_width,height = 0, 90, 60, 40, 40
# 7
btn7 = self.tk.Button(text='7', bd=2, font='黑体')
btn7.place( x=x0, y=y0, width=x_width, height=y_width)
# 8
btn8 = self.tk.Button(text='8', bd=2, font='黑体')
btn8.place( x=x0+x_width*1, y=y0, width=x_width, height=y_width)
# 9
btn9 = self.tk.Button(text='9', bd=2, font='黑体')
btn9.place( x=x0+x_width*2, y=y0, width=x_width, height=y_width)
# +
btn_add = self.tk.Button(text='+', bd=2, font='黑体')
btn_add.place( x=x0+x_width*3, y=y0, width=x_width, height=y_width) # 4
btn4 = self.tk.Button(text='4', bd=2, font='黑体')
btn4.place( x=x0, y=y0+y_width, width=x_width, height=y_width)
# 5
btn5 = self.tk.Button(text='5', bd=2, font='黑体')
btn5.place( x=x0+x_width*1, y=y0+y_width, width=x_width, height=y_width)
# 6
btn6 = self.tk.Button(text='6', bd=2, font='黑体')
btn6.place( x=x0+x_width*2, y=y0+y_width, width=x_width, height=y_width)
# -
btn_subtract = self.tk.Button(text='-', bd=2, font='黑体')
btn_subtract.place( x=x0+x_width*3, y=y0+y_width, width=x_width, height=y_width) # 1
btn1 = self.tk.Button(text='1', bd=2, font='黑体')
btn1.place( x=x0, y=y0+y_width*2, width=x_width, height=y_width)
# 2
btn2 = self.tk.Button(text='2', bd=2, font='黑体')
btn2.place( x=x0+x_width*1, y=y0+y_width*2, width=x_width, height=y_width)
# 3
btn3 = self.tk.Button(text='3', bd=2, font='黑体')
btn3.place( x=x0+x_width*2, y=y0+y_width*2, width=x_width, height=y_width)
# *
btn_mutiply = self.tk.Button(text='*', bd=2, font='黑体')
btn_mutiply.place( x=x0+x_width*3, y=y0+y_width*2, width=x_width, height=y_width) # 0
btn0 = self.tk.Button(text='0', bd=2, font='黑体')
btn0.place( x=x0, y=y0+y_width*3, width=x_width*2, height=y_width)
# .
btn_point = self.tk.Button(text='.', bd=2, font='黑体')
btn_point.place( x=x0+x_width*2, y=y0+y_width*3, width=x_width, height=y_width)
# /
btn_divid = self.tk.Button(text='/', bd=2, font='黑体')
btn_divid.place( x=x0+x_width*3, y=y0+y_width*3, width=x_width, height=y_width) # C后退
btn_clear = self.tk.Button( text='C', bd=2, font='黑体')
btn_clear.place( x=x0, y=y0+y_width*4, width=x_width, height=y_width) # C后退
btn_back = self.tk.Button( text='<==', bd=2, font='黑体')
btn_back.place( x=x0+x_width*1, y=y0+y_width*4, width=x_width, height=y_width) # =
btn_equal = self.tk.Button( text='=', bd=2, font='黑体')
btn_equal.place( x=x0+x_width*2, y=y0+y_width*4, width=x_width*2, height=y_width) # 绑定Button的点击事件
btn7.bind_class('Button', '<Button-1>', self.click_button) def click_button(self, event): # 获取点击的按钮信息信息
input_event = event.widget['text']
# 输入的按钮信息显示
self.label_show['text'] = self.label_show['text'] + input_event
# 异常捕获
try:
# 计算符号
cal_symbol = ['+', '-', '*', '/']
# 判定运算符号重复的时候,使用最后输入的符号
if self.label_show['text'][-1] in cal_symbol and self.label_show['text'][-2] in cal_symbol:
# 取重复符号前面的内容
header = self.label_show['text'][:-2]
footer = self.label_show['text'][-1]
self.label_show['text'] = header + footer
except:
pass # 进行普通计算
if event.widget['text'] == '=':
# 异常捕获
try:
res_bit = 2 # 计算保留的位数
res = eval(self.label_show['text'][:-1]) # 计算点击 “=” 之前的计算表达式
# print(type(res))
self.label_show['text'] = str(round(float(res), res_bit))
except ZeroDivisionError:
# 除法时,除数不能为0
self.mbox.showerror(title='错误', message='除法计算时!除数不能为0!')
except:
self.mbox.showerror(title='未知名错误', message='算式错误,请检查!') elif event.widget['text'] == '<==':
# 点击的‘<==’也计算在内,它占3个字符,因此是倒数4位去掉
back_res = self.label_show['text'][:-4]
self.label_show['text'] = back_res elif event.widget['text'] == 'C':
# 点击的‘C’也计算在内,因此是倒数2位去掉
self.label_show['text'] = '' if __name__=='__main__':
start = Calculator()

  

project3_NeedToLoginCalculator(需要进行登陆确认的计算器)的更多相关文章

  1. IdentityServer4 禁用 Consent screen page(权限确认页面)

    IdentityServer4 在登录完成的适合,会再跳转一次页面(权限确认),如下: 我之前以为 IdentityServer4 就是这样使用的,但实际业务场景并不需要进行权限确认,而是登陆成功后直 ...

  2. angularjs实现IOS8自带计算器

    最近看到一则面试题目,要求使用angularjs实现一个计算器,利用放假时间实现了一个仿iOS8风格的计算器,功能基本和iOS自带的计算器是一致的. 查看demo,接着给出实现过程. 首先创建angu ...

  3. MySQL数据库的登陆

    MySQL数据库的登陆 MySQL是一种C/S结构. C/S(Client/Server)客户端/服务器 MySQL的客户端: 1.cmd客户端 2.可视化图形界面 3.php代码 登陆: MySQL ...

  4. Python 爬虫五 进阶案例-web微信登陆与消息发送

    首先回顾下网页微信登陆的一般流程 1.打开浏览器输入网址 2.使用手机微信扫码登陆 3.进入用户界面 1.打开浏览器输入网址 首先打开浏览器输入web微信网址,并进行监控: https://wx.qq ...

  5. 前端验证用户登陆状态(vue.js)

    首先用户需要进行登陆(请求登陆接口),接口请求成功之后后台会返回对应的用户信息(可以把用户信息存放在浏览器缓存中),并且后台会设置浏览器的cookie值(可以在network->header-& ...

  6. MVC登陆认证简单设置

    首先,弄个基类 /// <summary> /// 所有控制器基类,里面重写了OnActionExecuted方法 /// </summary> public class Ba ...

  7. react-router-dom实现全局路由登陆拦截

    相比与vue的路由集中式管理,能够很好的进行统一的路由操作,react的路由看起来更乱,想要进行像vue的全局路由管理不是那么得心应手.在我们的项目中,有很多页面是需要登陆权限验证的,最好的方式就是能 ...

  8. asp.net 在AcquireRequestState事件中判断登陆验证。

    Global中添加AcquireRequestState事件. protected void Application_AcquireRequestState(object sender, EventA ...

  9. Hadoop生态圈-Knox网关的应用案例

    Hadoop生态圈-Knox网关的应用案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Knox网关简介 据Knox官网所述(http://knox.apache.org/) ...

随机推荐

  1. Delphi内建异常类 异常处理参考

    标签: delphiexceptionwindowscasting编程integer 2012-05-19 12:53 2579人阅读 评论(0) 收藏 举报 分类: Delphi(96) [详细过程 ...

  2. BAT批处理知识 及 常用批处理

    1.常用DOS命令:https://blog.csdn.net/qq_38676810/article/details/79584531  或  https://www.jb51.net/articl ...

  3. (转)VS2015基础 指定一个或多个项目执行 - 心少朴的博客

           慈心积善融学习,技术愿为有情学.善心速造多好事,前人栽树后乘凉.我今于此写经验,愿见文者得启发. 这个解决方案下,有两个项目, 看到黑体的project了吗?它就是指定执行的项目. 这两 ...

  4. qemu的动态翻译机制

    qemu的作者在QEMU, a Fast and Portable Dynamic Translator一文提到了qemu的动态翻译机制, 大致可以总结为如下过程: 目标代码中的一条指令 | |--( ...

  5. 【React-Native】---Android环境配置

    一.前言 本文主要内容是在Window系统下配置Android APP的开发环境,要配置RN的Android开发环境需要3个依赖 1.JDK(版本必须是 1.8) 2.Node(版本必须高于8.3) ...

  6. 剑指offer——59二叉搜索树的第k大节点

    题目描述 给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4.   题解: 考察的就是中序遍历 不过注意进行剪枝 cl ...

  7. Python CookBook(self report)

    Python CookBook 中文版:https://python3-cookbook.readthedocs.io/zh_CN/latest/copyright.html 英文版:https:// ...

  8. 条件sql ibatis

    <!-- 多条件查询 --><select id="MS-CUSTOM-PANDECT-INFO-BY-CONDITIONS" resultMap="R ...

  9. 5-MySQL-Ubuntu-操作数据库的基本操作语句

    注意: (1)每一条sql语句都是以分号(;)结尾! (2)数据库的默认charset不支持中文,所以每次在创建数据库的时候要指定字符集charset=utf8; (一) 查看当前时间: select ...

  10. git 常用命令 mv rm checkout revert reset

    关于上节讲的git add 时需要添加注释信息,也可以在git commit时再添加 laoni@DESKTOP-TPPLHIB MINGW64 /c/laoni/PycharmProjects/gi ...