from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap from PyQt5.QtSql import QSqlTableModel, QSqlDatabase from LoginUi import * from InterfaceUi import * from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QTableView, QWidget, QVBoxLayout, QComboBox, \ QButtonGroup, QMessageBox, QRadioButton from PyQt5.QtCore import Qt, QTimer, QTime, QDateTime import sys import pymysql import random from datetime import datetime user_now="" class LoginWindow(QMainWindow): def __init__(self): super().__init__() self.ui=Ui_LoginWindow() self.ui.setupUi(self) #去除边框 self.setWindowFlag(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) #阴影 self.shadow = QtWidgets.QGraphicsDropShadowEffect(self) self.shadow.setOffset(0,0) self.shadow.setBlurRadius(10) self.shadow.setColor(QtCore.Qt.black) self.ui.frame.setGraphicsEffect(self.shadow) #按钮切换登录和注册、以及按登录键实现页面跳转 self.ui.login_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(0)) self.ui.register_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(1)) self.ui.login_sure.clicked.connect(self.login_in) self.ui.register_sure.clicked.connect(self.register_in) self.show() def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.drag_position = event.globalPos() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.drag_position) event.accept() def mouseReleaseEvent(self, event): self.drag_position = None #注册账号 def register_in(self): account = self.ui.register_account.text() password_1 = self.ui.register_psw.text() password_2 = self.ui.register_psw2.text() # 判断是否输入为空 if not account or not password_1 or not password_2: self.ui.stackedWidget.setCurrentIndex(2) # 设置当前页面索引为空输入错误页面 return # 判断账号是否已存在 try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute('select cid from customer') rows = cur.fetchall() db.close() except Exception as e: print(f"Database error: {e}") self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面(可以调整索引) return # 提取所有现有账号 existing_accounts = [row[0] for row in rows] if account in existing_accounts: self.ui.stackedWidget.setCurrentIndex(3) # 设置当前页面索引为账号已存在错误页面 return # 判断两次输入密码是否正确 if password_1 == password_2: try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute(f"insert into customer(cid, cpsw) values('{account}', '{password_2}')") db.commit() # 提交事务 db.close() self.ui.stackedWidget.setCurrentIndex(4) # 设置当前页面索引为注册成功页面 except Exception as e: print(f"Database error: {e}") self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面 return else: self.ui.stackedWidget.setCurrentIndex(1) # 设置当前页面索引为密码不匹配错误页面 return #登录验证 def login_in(self): account = self.ui.login_account.text() password = self.ui.login_psw.text() # 检查输入框是否为空 if not account or not password: self.ui.stackedWidget.setCurrentIndex(2) # 设置当前页面索引为空输入错误页面 return account_list = [] password_list = [] try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute('select cid, cpsw from customer') rows = cur.fetchall() db.close() except Exception as e: print(f"Database error: {e}") self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面(可以调整索引) return for row in rows: account_list.append(row[0]) password_list.append(row[1]) # 验证账号和密码 for i in range(len(account_list)): if account == account_list[i] and password == password_list[i]: # 假设密码是字符串 global user_now user_now = account self.win = MainWindow() self.win.show() self.close() return # 如果没有匹配成功 self.ui.stackedWidget.setCurrentIndex(5) # 设置当前页面索引为账号或密码错误页面 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.model = None self.ui=Ui_MainWindow() self.ui.setupUi(self) self.initialize_image() #初始化图片 try: # 设置定时器 self.timer = QTimer(self) self.timer.timeout.connect(self.update_time) self.timer.start(1000) # 每秒更新一次 self.update_time() # 初始化时间显示 except Exception as e: print(e) #去除边框 self.setWindowFlag(QtCore.Qt.FramelessWindowHint) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) #阴影 self.shadow = QtWidgets.QGraphicsDropShadowEffect(self) self.shadow.setOffset(0,0) self.shadow.setBlurRadius(10) self.shadow.setColor(QtCore.Qt.black) self.ui.frame_6.setGraphicsEffect(self.shadow) #按钮切换到各个操作面 self.ui.logout_button.clicked.connect(self.log_out) self.ui.pushButton_home.clicked.connect(self.home_in) self.ui.pushButton_add.clicked.connect(self.add_in) self.ui.pushButton_get.clicked.connect(self.get_out) self.ui.pushButton_transfer.clicked.connect(self.transfer_in) self.ui.pushButton_look.clicked.connect(self.look_in) self.ui.pushButton_irt.clicked.connect(self.irt_in) self.ui.pushButton_info.clicked.connect(self.info_in) self.ui.pushButton_6.clicked.connect(lambda :self.ui.stackedWidget.setCurrentIndex(6)) # 创建 tableView 属性,并将其设置为 UI 文件中的 tableView 对象 self.tableView = self.ui.tableView # 这里的 self.ui.tableView 是 UI 文件中 tableView 对象的引用 self.show() def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.drag_position = event.globalPos() - self.frameGeometry().topLeft() event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.drag_position) event.accept() def mouseReleaseEvent(self, event): self.drag_position = None def update_time(self): current_time = QTime.currentTime() self.ui.label_17.setText(current_time.toString('hh:mm:ss')) def update_time(self): current_date_time = QDateTime.currentDateTime() formatted_time = current_date_time.toString('yyyy-MM-dd hh:mm:ss dddd') self.ui.label_17.setText(formatted_time) #初始化图片,应用在info中 def initialize_image(self): try: pixmap = QPixmap(":/images/images/123.jpg") self.ui.label_16.setScaledContents(True) # 让图片填充满 QLabel self.ui.label_16.setPixmap(pixmap) #self.ui.label_16.setPixmap(pixmap.scaled(self.ui.label_16.size(), Qt.KeepAspectRatio)) except Exception as e: print(f"Error loading image: {e}") #将account表中数据导出到home界面,使用的是tableWidget def home_in(self): global user_now self.ui.stackedWidget.setCurrentIndex(0) try: # 连接数据库 db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute(f"SELECT * FROM account WHERE cid = '{user_now}'") rows = cur.fetchall() db.commit() db.close() # 填充表格数据 for row_index, row_data in enumerate(rows): for col_index, data in enumerate(row_data): item = QTableWidgetItem(str(data)) item.setFlags(item.flags() & ~Qt.ItemIsEditable) # 禁止编辑 item.setTextAlignment(Qt.AlignCenter) #居中 self.ui.tableWidget.setItem(row_index, col_index, item) except Exception as e: print(f"Database error: {e}") # 连接数据库或执行查询时出错,可以在界面上显示相应的错误提示 def add_in(self): self.ui.stackedWidget.setCurrentIndex(1) self.ui.submit_button.clicked.connect(self.add_acc) def add_acc(self): global user_now try: accid = self.generator_accid() accbalance = self.ui.get_savings.text() current_date = datetime.now().date() acc_start = current_date.strftime('%Y-%m-%d') cid = user_now acctime = self.ui.deposit_time.currentText() # 获取 QGroupBox 中选中的 QRadioButton typebox = self.ui.type_box acctype = None for button in typebox.findChildren(QRadioButton): if button.isChecked(): acctype = button break if acctype is None: raise ValueError("未选择账户类型") acc_type = acctype.text() # 确认选择活期类型时长只能选择不定期 if acc_type == "活期" and acctime != "不定期": raise ValueError("活期账户的时长只能选择不定期") # 验证输入是否为空 if not accbalance or not acc_type or not acctime: raise ValueError("所有输入字段必须填写") accbalance_old=accbalance accbalance=int(accbalance) if acc_type=="定期": if acctime=='1年': accbalance=accbalance*(1+0.017) elif acctime=='2年': accbalance=accbalance*(1+0.019)**2 elif acctime=='3年': accbalance=accbalance*(1+0.022)**3 else: accbalance=accbalance*(1+0.024)**5 # 输出到控制台 print(accid, accbalance, acc_start, acctime, cid, acc_type) # 将新账户信息插入数据库 try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() query = "INSERT INTO account (accid, accbalance, acctime_start, accdur_time, cid, acc_type) VALUES (%s, %s, %s, %s, %s, %s)" cur.execute(query, (accid, accbalance, acc_start, acctime, cid, acc_type)) db.commit() db.close() QMessageBox.information(self, "成功", "账户添加成功") except Exception as db_error: print(f"数据库错误: {db_error}") QMessageBox.critical(self, "错误", "添加账户到数据库失败") return # 将信息写入文件 try: filename = f"{user_now}.txt" if acc_type=="定期": s = f"用户于{acc_start},开通账号:{accid},存取金额为{accbalance_old},期限为{acctime},到期后待取金额为{accbalance:.3f}\n" else: s = f"用户于{acc_start},开通账号:{accid},存取金额为{accbalance_old},期限为{acctime}\n" with open(filename, "a", encoding='UTF-8') as file: file.write(s) file.write("-" * 76 + "\n") print(f"信息已写入文件: {filename}") except Exception as file_error: print(f"文件写入错误: {file_error}") # 清空输入框 self.ui.get_savings.clear() self.ui.deposit_time.setCurrentIndex(0) for button in typebox.findChildren(QRadioButton): button.setAutoExclusive(False) button.setChecked(False) button.setAutoExclusive(True) except ValueError as ve: QMessageBox.critical(self, "错误", str(ve)) except Exception as e: print(e) QMessageBox.critical(self, "错误", f"发生错误: {e}") def generator_accid(self): while True: accid = random.randint(10000, 99999) try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute('SELECT * FROM account WHERE accid = %s', (accid,)) rows = cur.fetchone() if not rows: db.close() return accid else: print("Accid already exists. Generating a new one.") db.close() except Exception as e: print(f"Database error: {e}") return accid def get_out(self): self.ui.stackedWidget.setCurrentIndex(2) self.ui.sure_button1.clicked.connect(self.get_money) def get_money(self): global user_now accid=self.ui.accid_1.text() savings=self.ui.money_1.text() psw=self.ui.psw_sure1.text() self.ui.accid_1.clear() self.ui.money_1.clear() self.ui.psw_sure1.clear() # 检查取款金额是否为空 if not savings: QMessageBox.critical(self, "错误", "请输入取款金额") return try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() # 查询密码是否匹配 cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'") rows = cur.fetchone() if not rows or rows[0] != psw: QMessageBox.critical(self, "错误", "密码错误") db.close() return # 查询账户余额 cur.execute(f"SELECT accbalance, acc_type FROM account WHERE accid='{accid}' AND cid='{user_now}'") rows = cur.fetchone() if not rows: QMessageBox.critical(self, "错误", "账户不存在或不属于当前用户") db.close() return accbalance, acc_type = rows # 检查账户类型是否是活期 if acc_type != "活期": QMessageBox.critical(self, "错误", "账户类型不是活期,无法取款") db.close() return # 检查余额是否足够 if float(accbalance) < float(savings): QMessageBox.critical(self, "错误", "账户余额不足") db.close() return # 更新账户余额 new_balance = float(accbalance) - float(savings) cur.execute(f"UPDATE account SET accbalance={new_balance} WHERE accid='{accid}' AND cid='{user_now}'") db.commit() QMessageBox.information(self, "成功", f"成功取款 {savings} 元,当前余额为 {new_balance} 元") db.close() current_date = datetime.now().date() acctime= current_date.strftime('%Y-%m-%d') # 将信息写入文件 try: filename = f"{user_now}.txt" s = f"用户于{acctime},在账户{accid},取款{savings}元,当前余额为{new_balance}元\n" with open(filename, "a", encoding='UTF-8') as file: file.write(s) file.write("-" * 76 + "\n") print(f"信息已写入文件: {filename}") except Exception as file_error: print(f"文件写入错误: {file_error}") except Exception as e: print(f"数据库错误: {e}") QMessageBox.critical(self, "错误", "数据库错误") def transfer_in(self): self.ui.stackedWidget.setCurrentIndex(3) self.ui.sure_button2.clicked.connect(self.transfer) def transfer(self): out_account = self.ui.out_accid.text() in_account = self.ui.in_accid.text() out_saving = self.ui.out_money.text() psw = self.ui.sure_psw2.text() self.ui.out_accid.clear() self.ui.in_accid.clear() self.ui.out_money.clear() self.ui.sure_psw2.clear() # 检查输入是否为空 if not out_account or not in_account or not out_saving or not psw: QMessageBox.critical(self, "错误", "请输入完整信息") return try: db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() # 查询密码是否匹配 cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'") rows = cur.fetchone() if not rows or rows[0] != psw: QMessageBox.critical(self, "错误", "密码错误") db.close() return # 查询转出账号是否存在并且是活期类型 cur.execute( f"SELECT accbalance FROM account WHERE accid='{out_account}' AND cid='{user_now}' AND acc_type='活期'") rows = cur.fetchone() if not rows: QMessageBox.critical(self, "错误", "转出账号不存在或不是活期类型") db.close() return out_balance = float(rows[0]) # 检查转出金额是否大于转出账号余额 if float(out_saving) > out_balance: QMessageBox.critical(self, "错误", "转出账号余额不足") db.close() return # 查询收款账号是否存在并且是活期类型 cur.execute(f"SELECT acc_type FROM account WHERE accid='{in_account}' AND acc_type='活期'") rows = cur.fetchone() if not rows: QMessageBox.critical(self, "错误", "收款账号不存在或不是活期类型") db.close() return # 更新转出账号余额和收款账号余额 new_out_balance = out_balance - float(out_saving) cur.execute( f"UPDATE account SET accbalance={new_out_balance} WHERE accid='{out_account}' AND cid='{user_now}'") cur.execute(f"UPDATE account SET accbalance=accbalance+{out_saving} WHERE accid='{in_account}'") # 获取收款账号所属用户的cid和新余额 cur.execute(f"SELECT cid FROM account WHERE accid='{in_account}'") row = cur.fetchone() if not row: QMessageBox.critical(self, "错误", "获取收款账号信息失败") db.close() return recipient_cid = row[0] cur.execute(f"SELECT accbalance FROM account WHERE accid='{in_account}'") row = cur.fetchone() if not row: QMessageBox.critical(self, "错误", "获取收款账号余额失败") db.close() return new_in_balance = float(row[0]) db.commit() QMessageBox.information(self, "成功", f"成功转账 {out_saving} 元到账户 {in_account}") db.close() # 写入转账信息到文件 try: current_date = datetime.now().date() acctime = current_date.strftime('%Y-%m-%d') filename1 = f"{user_now}.txt" filename2 = f"{recipient_cid}.txt" out_info = f"用户于{acctime},账号:{out_account}转给{in_account}, {out_saving}元,当前余额为{new_out_balance}元\n" in_info = f"用户于{acctime},账号:{in_account} 收到{out_saving}元,当前余额为{new_in_balance}元\n" with open(filename1, "a", encoding='UTF-8') as file1: file1.write(out_info) file1.write("-" * 76 + "\n") with open(filename2, "a", encoding='UTF-8') as file2: file2.write(in_info) file2.write("-" * 76 + "\n") print(f"信息已写入文件: {filename1} 和 {filename2}") except Exception as file_error: print(f"文件写入错误: {file_error}") except Exception as e: print(f"数据库错误: {e}") QMessageBox.critical(self, "错误", "数据库错误") def look_in(self): try: global user_now self.ui.stackedWidget.setCurrentIndex(4) textname=f"{user_now}.txt" with open(textname,'r',encoding='utf-8') as f: f.seek(0) str=f.read() self.ui.textEdit.setPlainText(str) except Exception as e: print(e) def irt_in(self): self.ui.stackedWidget.setCurrentIndex(5) try: # 连接数据库 db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank') cur = db.cursor() cur.execute("SELECT * FROM irt") rows = cur.fetchall() db.commit() db.close() # 设置表格行数 self.ui.tableWidget_2.setRowCount(len(rows)) # 填充表格数据 for row_index, row_data in enumerate(rows): for col_index, data in enumerate(row_data): item = QTableWidgetItem(str(data)) item.setFlags(item.flags() & ~Qt.ItemIsEditable) # 禁止编辑 item.setTextAlignment(Qt.AlignCenter) # 居中 self.ui.tableWidget_2.setItem(row_index, col_index, item) except Exception as e: print(f"Database error: {e}") # 连接数据库或执行查询时出错,可以在界面上显示相应的错误提示 def info_in(self): try: # 切换到包含 QTableView 的页面 self.ui.stackedWidget.setCurrentIndex(7) # 设置模型 self.model = QStandardItemModel(0, 7) self.model.setHorizontalHeaderLabels(['身份证号', '姓名', '性别', '年龄', '电话号码', '户籍', '密码']) self.tableView.setModel(self.model) # 加载数据 self.load_data() # 使表格可编辑 self.tableView.setEditTriggers(QTableView.AllEditTriggers) # 捕捉模型数据改变信号 self.model.itemChanged.connect(self.update_database) except Exception as e: print(f"Error in info_in: {e}") # 连接 MySQL 并获取数据 def load_data(self): global user_now try: connection = pymysql.connect( host='127.0.0.1', user='root', password='20021220', database='pybank' ) cursor = connection.cursor() cursor.execute(f"SELECT * FROM customer where cid='{user_now}'") data = cursor.fetchall() cursor.close() connection.close() for row in data: items = [QStandardItem(str(field)) for field in row] for item in items: item.setTextAlignment(Qt.AlignCenter) self.model.appendRow(items) except Exception as e: print(f"Error loading data: {e}") def update_database(self, item): row = item.row() col = item.column() new_value = item.text() print(row, col, new_value) try: # 获取主键(第一列是主键) primary_key = self.model.item(row, 0).text() # 映射列名 columns = ['cid', 'cname', 'csex', 'cage', 'cnumber', 'caddress', 'cpsw'] column_name = columns[col] # 更新数据库 connection = pymysql.connect( host='127.0.0.1', user='root', password='20021220', database='pybank' ) cursor = connection.cursor() query = f"UPDATE customer SET {column_name} = %s WHERE cid = %s" cursor.execute(query, (new_value, primary_key)) connection.commit() cursor.close() connection.close() print(f"Updated row {row}, column {col} with new value {new_value}") except Exception as e: print(f"Error updating database: {e}") #退出当前账号回到登录界面 def log_out(self): global user_now self.close() self.login = LoginWindow() user_now = "" if __name__ == '__main__': app = QApplication(sys.argv) win = LoginWindow() sys.exit(app.exec_())