You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

475 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import tkinter as tk
import DataB
import Record
from datetime import datetime
from PIL import Image, ImageTk
import tkinter.messagebox
from tkinter import ttk
# 一、界面类
class Windows:
# 01存放用户信息的列表
user_info = []
# 01.初始化
def __init__(self, master=None):
self.atm = ATM() # ATM功能类
self.master = master
self.login() # 选择银行卡
self.pwd_judge = 0 # 密码验证
# 02 加载背景图像
def loadImage(self, width, height, bgt):
# 使用Pillow加载图像
self.background_image = Image.open(bgt) # 这里可以使用 JPG 格式
self.background_image = self.background_image.resize((width, height), Image.Resampling.NEAREST) # 可选:调整图像大小
self.background_image = ImageTk.PhotoImage(self.background_image)
# 创建一个Label来显示图像
self.background_label = tk.Label(self.root1, image=self.background_image)
self.background_label.place(relwidth=1, relheight=1)
# 03 程序入口
def login(self):
self.root1 = tk.Frame(self.master)
w = 680
h = 450
self.root1['width'] = w
self.root1['height'] = h
# 得到屏幕宽度和高度
sw = root.winfo_screenwidth()
# 得到屏幕高度
sh = root.winfo_screenheight()
# 窗口居中
x = (sw - w) / 2
y = (sh - h) / 2
root.geometry('%dx%d+%d+%d' % (w, h, x, y))
# 加载背景图像
self.loadImage(680, 450, 'image/back.jpg')
self.lableFrameName = tk.Label(self.root1, text='欢迎来到模拟ATM系统', font=('微软雅黑', 20))
self.lableFrameName.place(x=200, y=50)
self.btn1 = tk.Button(self.root1, text='注册', font=('微软雅黑', 18), width=8, command=self.apply)
self.btn1.place(x=270, y=150)
# 登录按钮
self.btn2 = tk.Button(self.root1, text='登录', font=('微软雅黑', 18), width=8, command=self.choose_card)
self.btn2.place(x=270, y=250)
self.root1.pack()
# 04 注册窗口
def apply(self):
if self.root1:
self.root1.destroy()
self.master.geometry("680x450")
self.root1 = tk.Frame(self.master)
self.root1['width'] = 680
self.root1['height'] = 450
# 加载背景图像
self.loadImage(680, 450, 'image/bg.jpg')
# 身份证号码
self.labelIdName = tk.Label(self.root1, text='身份证:', font=('微软雅黑', 18))
self.labelIdName.place(x=150, y=60, anchor='e')
self.varIdName = tk.StringVar(self.root1, value='')
self.entryIdName = tk.Entry(self.root1, font=('微软雅黑', 18), width=25, textvariable=self.varIdName)
self.entryIdName.place(x=180, y=60, anchor='w')
self.entryIdName.focus_set() # 获得焦点
# 账号
self.labelUserName = tk.Label(self.root1, text='账 号:', font=('微软雅黑', 18))
self.labelUserName.place(x=150, y=120, anchor='e')
self.varUserName = tk.StringVar(self.root1, value='')
self.entryUserName = tk.Entry(self.root1, font=('微软雅黑', 18), width=25, textvariable=self.varUserName)
self.entryUserName.place(x=180, y=120, anchor='w')
self.entryUserName.focus_set() # 获得焦点
# 密码
self.labelPwd = tk.Label(self.root1, text='密 码:', font=('微软雅黑', 18))
# justify=RIGHT,anchor='w',width=80)
self.labelPwd.place(x=150, y=180, anchor='e') # grid(column=0,row=1,pady=10)
self.varPwd = tk.StringVar(self.root1, value='')
self.entryPwd = tk.Entry(self.root1, show='*', font=('微软雅黑', 18), width=25, textvariable=self.varPwd)
self.entryPwd.place(x=180, y=180, anchor='w') # grid(column=1,row=1,pady=10)
# 注册按钮
self.btnz = tk.Button(self.root1, text='注册', font=('微软雅黑', 18), width=8,
command=self.Jlogin)
self.btnz.place(x=180, y=250)
# 登录按钮
self.btnf = tk.Button(self.root1, text='登录', font=('微软雅黑', 18), width=8,
command=self.choose_card)
self.btnf.place(x=350, y=250)
self.root1.pack()
# 05 判断是否注册成功
def Jlogin(self):
name = self.entryUserName.get()
pwd = self.entryPwd.get()
id = self.entryIdName.get()
if id == '':
tk.messagebox.showinfo('提示', '身份证不能为空')
elif len(name) != 6:
tk.messagebox.showinfo('提示', '账号必须为6位的数字或字符')
elif len(pwd) < 6:
tk.messagebox.showinfo('提示', '密码不能小于6位')
elif id != '' and len(name) == 6 and len(pwd) >= 6:
self.flag = True
for x in DataB.a:
if x[0] == name:
self.flag = False
tk.messagebox.showinfo('提示', '该账户已存在,请重新注册!')
if self.flag:
DataB.insert_data(name, pwd, id)
self.atm.Card.append([name, pwd, 0.00, '', 0, id])
tk.messagebox.showinfo('提示', '注册成功')
self.root1.destroy()
self.login()
# 06 返回程序入口
def Flogin(self):
self.root1.destroy()
self.login()
# 07 选择银行卡
def choose_card(self):
if self.root1:
self.root1.destroy()
self.master.geometry("680x450")
self.root1 = tk.Frame(self.master)
self.root1['width'] = 680
self.root1['height'] = 450
# 加载背景图像
self.loadImage(680, 450, 'image/bg11.jpg')
# 返回注册按钮
self.btnfs = tk.Button(self.root1, text='注册', font=('微软雅黑', 11), width=8,
command=self.apply)
self.btnfs.place(x=0, y=0)
self.lbl1 = tk.Label(self.root1, text='选择银行卡账号:', font=('microsoft yahei', 18))
self.lbl1.place(x=20, y=150)
self.cbox1 = ttk.Combobox(self.root1,width=25,font=('microsoft yahei', 18))
self.cbox1['values'] = self.atm.choose_card()
self.cbox1.place(x=220, y=150)
self.btnc = tk.Button(self.root1, text='确认', font=('microsoft yahei', 12),
command=lambda: self.confirm(self.cbox1.get()))
self.btnc.place(x=600, y=150)
self.root1.pack()
# 08 确认选择银行卡
def confirm(self, user):
if user != '':
self.root1.destroy()
self.master.geometry("680x450")
self.root1 = tk.Frame(self.master)
self.root1['width'] = 680
self.root1['height'] = 450
# 加载背景图像
self.loadImage(680, 450, 'image/bg5.jpg')
# 返回按钮
self.btnfc = tk.Button(self.root1, text='返回', font=('微软雅黑', 11), width=8,
command=self.Fchoose)
self.btnfc.place(x=0, y=0)
self.lbl2 = tk.Label(self.root1, text='账号: ' + user , font=('microsoft yahei', 15), width=30, anchor='w', justify='left')
self.lbl2.place(x=20, y=150)
self.lbl3 = tk.Label(self.root1, text='密码:', font=('microsoft yahei', 15))
self.lbl3.place(x=20, y=200)
self.entry1 = tk.Entry(self.root1, show="*", font=('微软雅黑', 15), width=24)
self.entry1.place(x=90, y=200)
self.btnq = tk.Button(self.root1, text='确认', font=('microsoft yahei', 15), width=10,
command=lambda: self.T_F(user, self.entry1.get()))
self.btnq.place(x=120, y=260)
self.root1.pack()
else:
tkinter.messagebox.showinfo('提示', '请选择银行卡号!')
# 09.登录密码验证
def T_F(self, user, pwd):
self.flag = False
for i in self.atm.Card:
if i[0] == user:
Windows.user_info = i
if i[4] == 1:
tkinter.messagebox.showinfo('提示', '银行卡已冻结,请带上身份证前往柜台解锁!')
exit()
if i[1] == pwd and i[4] == 0:
self.flag = True
break
if self.flag:
self.c_to_f()
elif self.pwd_judge == 4:
self.atm.card_lock(user)
tkinter.messagebox.showinfo('提示', '密码错误5次银行卡已冻结请带上身份证前往柜台解锁')
self.choose_card()
else:
self.pwd_judge += 1
tkinter.messagebox.showinfo('提示', '密码错误!你还有{0}次机会'.format(5 - self.pwd_judge))
# 10 登录成功跳转
def c_to_f(self):
tkinter.messagebox.showinfo('提示', '验证通过即将进入ATM系统')
self.root1.destroy()
self.function_board()
# 11.功能界面设计
def function_board(self):
if self.root1:
self.root1.destroy()
self.master.geometry("680x450")
self.root1 = tk.Frame(self.master)
self.root1['width'] = 680
self.root1['height'] = 450
# 加载背景图像
self.loadImage(680, 450, 'image/bg4.jpg')
self.buttons = [["查询余额", "存款", "取款", "办理其他业务"],
["转账", "查看流水", "修改密码","退卡"]]
for r in range(2):
for c in range(4):
def cmd(key=self.buttons[r][c]):
self.click(key)
self.B = tk.Button(self.root1, text=self.buttons[r][c], font=('microsoft yahei', 15), width=10, bg="#C0C0C0",
command=cmd)
self.B.place(x=r * 150 + 200, y=c * 55 + 100)
self.root1.pack()
# 12 点击按钮,执行相应功能
def click(self, key):
self.root1.destroy()
if key == '查询余额':
self.Fscreen()
self.lbl4 = tk.Label(self.root1, text='卡内余额:' + str(Windows.user_info[2]), width=25,anchor='w', justify='left',
font=('microsoft yahei', 20))
self.lbl4.place(x=120, y=140)
self.btn3 = tk.Button(self.root1, text='返回', font=('microsoft yahei', 15), width=10, command=self.function_board)
self.btn3.place(x=0, y=0)
elif key in ('存款', '取款'):
self.Fscreen()
self.lbl4 = tk.Label(self.root1, text='输入' + key + '金额:',
font=('microsoft yahei', 15))
self.lbl4.place(x=90, y=100)
self.entry2 = tk.Entry(self.root1, font=('microsoft yahei', 15))
self.entry2.place(x=250, y=100)
self.btn3 = tk.Button(self.root1, text='确认', width=15,
command=lambda: self.atm.add_decrease_money
(Windows.user_info[0], self.entry2.get(), key))
self.btn3.place(x=180, y=200)
elif key == '查看流水':
self.Fscreen()
self.lbl4 = tk.LabelFrame(self.root1, text='流水记录')
self.lbl4.place(x=50, y=60)
self.text = tk.Text(self.lbl4, bg='white', height=24, width=80)
self.text.insert(0.0, Windows.user_info[3])
self.text.pack()
elif key == '转账':
self.Fscreen()
self.lbl1 = tk.Label(self.root1, text='转入卡的账号:',width=12, font=('microsoft yahei', 18))
self.lbl1.place(x=20, y=150)
self.cbox1 = ttk.Combobox(self.root1, width=20,font=('microsoft yahei', 18))
self.cbox1['values'] = self.atm.choose_card()
self.cbox1.place(x=220, y=150)
self.lbl2 = tk.Label(self.root1, text='转账金额:', width=12, font=('microsoft yahei', 18), anchor='w', justify='left')
self.lbl2.place(x=20, y=220)
self.entry2 = tk.Entry(self.root1,width=20,font=('microsoft yahei', 18))
self.entry2.place(x=220, y=220)
self.btn1 = tk.Button(self.root1, text='确认', width=10,
font=('microsoft yahei', 18),
command=lambda: self.atm.to_user
(Windows.user_info[0], self.cbox1.get(), self.entry2.get()))
self.btn1.place(x=260, y=350)
elif key == "修改密码":
self.Fscreen()
# 输入旧密码
self.labelOldPwd = tk.Label(self.root1, text='输入旧密码:', font=('微软雅黑', 18))
# justify=RIGHT,anchor='w',width=80)
self.labelOldPwd.place(x=150, y=90, anchor='e') # grid(column=0,row=1,pady=10)
self.varOldPwd = tk.StringVar(self.root1, value='')
self.entryOldPwd = tk.Entry(self.root1, show='*', font=('微软雅黑', 18), width=25, textvariable=self.varOldPwd)
self.entryOldPwd.place(x=180, y=90, anchor='w') # grid(column=1,row=1,pady=10)
# 输入新密码
self.labelNewPwd = tk.Label(self.root1, text='输入新密码:', font=('微软雅黑', 18))
# justify=RIGHT,anchor='w',width=80)
self.labelNewPwd.place(x=150, y=160, anchor='e') # grid(column=0,row=1,pady=10)
self.varNewPwd = tk.StringVar(self.root1, value='')
self.entryNewPwd = tk.Entry(self.root1, show='*', font=('微软雅黑', 18), width=25, textvariable=self.varNewPwd)
self.entryNewPwd.place(x=180, y=160, anchor='w') # grid(column=1,row=1,pady=10)
self.btnz = tk.Button(self.root1, text='确认修改', font=('微软雅黑', 18), width=8,
command=lambda: self.atm.Change(Windows.user_info[0], self.entryOldPwd.get(), self.entryNewPwd.get()))
self.btnz.place(x=220, y=250)
elif key=="办理其他业务":
self.Fscreen()
self.lblq = tk.Label(self.root1, text='如需办理其他业务,请移步柜台咨询!' , width=30, anchor='w',
justify='left',
font=('microsoft yahei', 20))
self.lblq.place(x=120, y=140)
else:
self.root1.destroy()
tk.messagebox.showinfo('提示', '感谢您的使用,请收好您的银行卡!')
self.choose_card()
def Fscreen(self):
self.root1 = tk.Frame(self.master)
self.root1['width'] = 680
self.root1['height'] = 450
# 加载背景图像
self.loadImage(680, 450, 'image/function.jpg')
# 左上角返回按钮
self.btn3 = tk.Button(self.root1, text='返回', font=('microsoft yahei', 15), width=10,
command=self.function_board)
self.btn3.place(x=0, y=0)
self.root1.pack()
# 返回银行卡选择界面
def Fchoose(self):
self.root1.destroy()
self.choose_card()
class ATM:
# 01初始化参数
def __init__(self):
# 存放账户的列表
self.Card = []
self.read_card()
# 02读卡功能
def read_card(self):
DataB.select_data()
for x in DataB.a:
self.Card.append(x) # 列表中存放的元素还是列表
# 02 锁卡功能, 不会用,搞不明白,重写
def card_lock(self, user):
for i in self.Card:
if i[0] == user:
i[4] = 1
break
self.update_Card()
# 03 增加账号,注册办卡, 可以删除
def insert_card(self, user, pwd):
self.flag = True
for x in DataB.a:
if x[0] == user:
self.flag = False
tk.messagebox.showinfo('提示', '该账户已存在,请重新注册!')
if self.flag:
DataB.insert_data(user, pwd)
tk.messagebox.showinfo('提示', '注册成功')
# 04获取时间
def timeNow(self):
# 获取当前时间
now = datetime.now()
# 将时间转换为字符串,返回当前时间
formatted_time = f"{now:%Y年%m月%d日 %H:%M:%S}"
return formatted_time
# 05存款取款操作
def add_decrease_money(self, user, money, key):
if money == '':
tk.messagebox.showinfo('提示', '请输入金额')
else:
if key == '存款':
for i in self.Card:
if i[0] == user:
i[2] += int(money)
Record.insert_data(user,ATM.timeNow(self),f'存入了{money}',i[2])
i[3] += '你在{0}存入了{1}元,现有余额为{2}\n'.\
format(ATM.timeNow(self), money, i[2])
break
tk.messagebox.showinfo('提示', '存入成功')
self.update_Card()
else: # 取款
for i in self.Card:
if i[0] == user:
i[2] -= int(money)
if i[2] > 0:
Record.insert_data(user,ATM.timeNow(self),f'取出了{money}',i[2])
i[3] += '你在{0}取出了{1}元,现有余额为{2}\n'. \
format(ATM.timeNow(self), money, i[2])
tk.messagebox.showinfo('提示', '取出成功')
break
else:
tk.messagebox.showinfo('提示', '余额不足')
i[2] += int(money)
break
self.update_Card()
#06 转账功能
def to_user(self, user1, user2, money):
if money == '':
tk.messagebox.showinfo('提示', '请输入金额')
elif user1 == user2:
tk.messagebox.showinfo('提示', '操作失败,转入的是本账号')
else:
self.flag = True
for i in self.Card:
if i[0] == user1:
i[2] -= int(money)
if i[2] < 0:
tk.messagebox.showinfo('提示', '余额不足')
i[2] += int(money)
self.flag = False
break
Record.insert_data(user1, ATM.timeNow(self),f'"{user2}"账户转出了{money}',i[2])
i[3] += '你在{0}向“{1}”账户转出了{2}元,现有余额为{3}\n'. \
format(ATM.timeNow(self), user2, money, i[2])
break
if self.flag:
for i in self.Card:
if i[0] == user2:
i[2] += int(money)
Record.insert_data(user2, ATM.timeNow(self),f'收到了来自账户“{user1}”转入的{money}',i[2])
i[3] += '你在{0}收到了账户“{1}”转入的{2}元,现有余额为{3}\n'. \
format(ATM.timeNow(self),user1, money, i[2])
tk.messagebox.showinfo('提示', '转账成功')
self.update_Card()
# 05 修改密码
def Change(self, user, oldP, newP):
for i in self.Card:
if i[0] == user:
if i[1] == oldP and len(newP) >= 6:
i[1] = newP
tk.messagebox.showinfo('提示', '密码修改成功')
self.update_Card()
break
elif len(newP)< 6:
tk.messagebox.showinfo('提示', '新密码不能小于6位')
else:
tk.messagebox.showinfo('提示', '旧密码输入错误')
# 06更新数据
def update_Card(self):
for i in self.Card:
DataB.update_data(i[0], i[1],i[2], i[3], i[4], i[5])
# 07选择银行卡
def choose_card(self):
return [i[0] for i in self.Card]
if __name__ == '__main__':
root = tk.Tk()
root.title('Python ATM系统-bhml')
root.resizable(width=False, height=False)
app = Windows(root)
root.mainloop()