計算機軟體實習專案四 —— 校園一卡通管理系統 (程式碼實現) 12-27
程式碼實現(校園一卡通管理系統)
這個專案依舊選擇用Python+PyQt5來進行開發,資料庫部分則選擇使用mysql。
我主要負責實現主視窗部分的學生基本資訊欄和交易記錄欄的增刪改查、批量插入、批量刪除等功能,同時負責部分UI介面的製作以及後端mysql資料庫互動方法的編寫等。
目錄
一、主函式(main.py)
主函式用來建立各個視窗,並且建立各個視窗之間的關係。
from PyQt5.QtWidgets import QApplication
from BatchInsertedWindow import BatchInsertedWindow
from ForgetWindow import ResetWindow, SecurityQuestionWindow
from LoginWindow import LoginWindow
from MainWindow import MainWindow
from InsertWindow import InsertWindow
import sys
if __name__ == "__main__":
app = QApplication(sys.argv)
login_widget = LoginWindow() # 視窗控制元件
login_widget.show()
main_widget = MainWindow() # 視窗控制元件
forget_widget = SecurityQuestionWindow() # 密保視窗
reset_widget = ResetWindow() # 重置密碼視窗
insert_widget = InsertWindow() # 視窗控制元件
batch_insert_widget = BatchInsertedWindow() # 批量插入視窗
login_widget.signal.connect(main_widget.show) # 連線槽函式
login_widget.forget_signal.connect(forget_widget.show) # 顯示忘記密碼視窗
forget_widget.signal.connect(reset_widget.show) # 顯示重置密碼視窗
forget_widget.back_signal.connect(login_widget.show) # 顯示登入視窗
reset_widget.signal.connect(login_widget.show) # 回到登入視窗
reset_widget.back_signal.connect(login_widget.show) # 回到登入視窗
main_widget.batch_signal.connect(batch_insert_widget.show) # 顯示批量插入視窗
main_widget.insert_signal.connect(insert_widget.show) # 連線槽函式
insert_widget.inserted_signal.connect(main_widget.query) # 更新資料
sys.exit(app.exec_())
二、登入視窗(LoginWindow.py)
登入視窗負責使用者身份驗證,以及彈出忘記密碼視窗等功能。
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import ctypes
from PyQt5.QtWidgets import QMainWindow, QLineEdit, QMessageBox, QWidget
from Functions import load
from Login_UI import Ui_LoginWindow
class LoginWindow(QtWidgets.QMainWindow, Ui_LoginWindow):
signal = pyqtSignal()
forget_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('校園一卡通管理系統登入') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
# self.setStyleSheet('QWidget{background-color:%s}' % QColor(222, 222, 222).name()) # 設定視窗背景色
self.setWindowOpacity(0.95) # 設定整個計算器視窗的透明度
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 工作列圖示
self.setWindowFlags(Qt.FramelessWindowHint)
self.show()
self.set_input() # 輸入賬號和輸入密碼的設定
# 將訊號連線到對應槽函式
self.login_button.clicked.connect(self.username_password)
self.forget.clicked.connect(self.forget_password)
self.login_close.clicked.connect(QCoreApplication.instance().quit)
# 輸入賬號和輸入密碼的設定
def set_input(self):
self.input_username.setPlaceholderText("請輸入賬號") # 灰色的佔位符
self.input_password.setPlaceholderText("請輸入密碼") # 灰色的佔位符
self.input_username.setContextMenuPolicy(Qt.NoContextMenu) # 禁止複製貼上
self.input_password.setContextMenuPolicy(Qt.NoContextMenu) # 禁止複製貼上
self.input_password.setEchoMode(QLineEdit.Password) # 輸入時呈現圓點,不顯示密碼
# 檢查使用者名稱與密碼是否匹配
def username_password(self):
if load(self.input_username.text(), self.input_password.text()):
self.hide()
self.signal.emit() # 發射訊號
else:
QMessageBox.warning(self, "錯誤", "賬號或密碼錯誤!")
self.input_password.setText('')
pass
# 忘記密碼按鈕觸發的訊號
def forget_password(self):
self.hide()
self.forget_signal.emit() # 發射忘記密碼訊號
# 鍵盤登入
def keyPressEvent(self, event):
QWidget.keyPressEvent(self, event)
key = event.key()
if key == Qt.Key_Enter:
self.username_password()
三、忘記密碼視窗(ForgetWindow.py)
忘記密碼視窗負責校驗密保問題,判斷使用者是否擁有修改密碼許可權。
在這裡插入程式碼片from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import ctypes
import re
from PyQt5.QtWidgets import QMessageBox, QWidget, QLineEdit
from Functions import SecurityQuestion, ResetPassword
from SecurityQuestion_UI import Ui_SecurityQuestionWindow
from Reset_UI import Ui_ResetWindow
global username_changing
class SecurityQuestionWindow(QtWidgets.QMainWindow, Ui_SecurityQuestionWindow):
signal = pyqtSignal()
back_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('忘記密碼') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 工作列圖示
self.setWindowFlags(Qt.FramelessWindowHint)
# 將訊號連線到對應槽函式
self.confirm_button.clicked.connect(self.security_question)
self.back_button.clicked.connect(self.back_to_login)
self.close_button.clicked.connect(QCoreApplication.instance().quit)
# 檢查使用者名稱與密保是否匹配
def security_question(self):
if SecurityQuestion(self.input_username.text(), self.input_security.text()):
global username_changing
username_changing = self.input_username.text()
self.input_username.setText('')
self.input_security.setText('')
self.hide()
self.signal.emit() # 發射訊號
else:
QMessageBox.warning(self, "錯誤", "密保錯誤!")
self.input_security.setText('')
# 鍵盤確認
def keyPressEvent(self, event):
QWidget.keyPressEvent(self, event)
key = event.key()
if key == Qt.Key_Enter:
self.security_question()
def back_to_login(self):
self.hide()
self.back_signal.emit() # 觸發返回登陸介面的訊號
class ResetWindow(QtWidgets.QMainWindow, Ui_ResetWindow):
signal = pyqtSignal()
back_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('重置密碼') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
# self.setStyleSheet('QWidget{background-color:%s}' % QColor(222, 222, 222).name()) # 設定視窗背景色
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 工作列圖示
self.setWindowFlags(Qt.FramelessWindowHint)
self.set_input() # 輸入密碼的設定
# 將訊號連線到對應槽函式
self.submit_button.clicked.connect(self.Reset)
self.back_button.clicked.connect(self.back_to_login)
self.close_button.clicked.connect(QCoreApplication.instance().quit)
def set_input(self):
self.input_pass1.setContextMenuPolicy(Qt.NoContextMenu) # 禁止複製貼上
self.input_pass2.setContextMenuPolicy(Qt.NoContextMenu) # 禁止複製貼上
self.input_pass1.setEchoMode(QLineEdit.Password) # 輸入時呈現圓點,不顯示密碼
self.input_pass2.setEchoMode(QLineEdit.Password) # 輸入時呈現圓點,不顯示密碼
# 檢查使用者名稱與密保是否匹配
def Reset(self):
regx = re.compile(r"^[a-zA-Z]\w{5,14}")
global username_changing
if username_changing != '' and self.input_pass1.text() == self.input_pass2.text() and regx.match(self.input_pass1.text()) is not None:
if regx.match(self.input_pass1.text()).group() == self.input_pass1.text():
ResetPassword(username_changing, self.input_pass1.text())
QMessageBox.information(self, "資訊", "修改密碼成功!")
self.input_pass1.setText('')
self.input_pass2.setText('')
self.hide()
self.signal.emit() # 發射訊號
else:
QMessageBox.warning(self, "警告", "請輸入符合條件的密碼!")
self.input_pass1.setText('')
self.input_pass2.setText('')
else:
if self.input_pass1.text() != self.input_pass2.text():
QMessageBox.warning(self, "警告", "兩次輸入的密碼不一致,請重新輸入!")
else:
QMessageBox.warning(self, "警告", "請輸入符合條件的密碼!")
self.input_pass1.setText('')
self.input_pass2.setText('')
# 鍵盤確認
def keyPressEvent(self, event):
QWidget.keyPressEvent(self, event)
key = event.key()
if key == Qt.Key_Enter:
self.Reset()
def back_to_login(self):
self.hide()
self.back_signal.emit() # 觸發返回登陸介面的訊號
四、主視窗(MainWindow.py)(重點)
這部分是我重點負責的部分,我將比較詳細的解釋程式碼。
1. 成員變數
# 在PyQt5裡建立的是QMainWindow,不是Widget,需要注意的是,建立的元素一定要呼叫正確。
class MainWindow(QMainWindow, Ui_MainWindow):
insert_signal = pyqtSignal() # 定義插入訊號
batch_signal = pyqtSignal() # 定義批量插入訊號
query_flag = 0 # 查詢標記
check_list = [] # 確認列表
delete_f = -1 # 批量刪除選定初始行
delete_t = -1 # 批量刪除選定末尾行
2. 建構函式
註釋寫的比較明瞭,就不過多贅述。
def __init__(self):
# 初始化視窗
super().__init__()
self.setupUi(self)
self.setWindowTitle('校園一卡通管理系統') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
self.setWindowOpacity(1) # 設定整個視窗的透明度為不透明
# 初始化編輯框
self.lineEdit_id.setText("")
self.lineEdit_name.setText("")
self.lineEdit_phonenumber.setText("")
# 初始化下拉框
self.comboBox_sex.addItems(["", "男", "女"])
self.comboBox_college.addItems(["", "計算機學院", "機械學院", "外國語學院"])
self.comboBox_major.addItems(["", "物聯網工程", "電腦科學與技術", "軟體工程", "通訊工程", "資訊保安"])
self.comboBox_sex_2.addItems(["", "充值", "飲食", "電費", "水費", "車費"])
# 初始化標記
self.query_flag = 0
self.check_list = []
self.delete_f = -1
self.delete_t = -1
# 訊號和槽函式繫結
# 欄目1(學生基本資訊)
self.pushButton_query.clicked.connect(self.query) # 為按鈕新增點選事件
self.comboBox_college.activated.connect(self.update_ComboBox) # 如果下拉框被啟用就更新子下拉框
self.pushButton_insert.clicked.connect(self.insert_button_signal) # 彈出插入視窗
self.pushButton_delete.clicked.connect(self.deleteConfirm) # 刪除操作
self.tableWidget.itemChanged.connect(self.update_tableWidget) # 查詢操作
self.tableWidget.cellPressed.connect(self.update_flag) # 更新查詢標記
self.tableWidget.itemSelectionChanged.connect(self.update_selected) # 更新選擇區域
self.pushButton_batch.clicked.connect(self.batch_button_signal) # 批量插入
# 欄目2(交易記錄)
self.pushButton_query_2.clicked.connect(self.upadate_tableWidget2) # 查記錄
# 欄目3(充值介面按鈕繫結)
self.top_up_button.clicked.connect(self.top_up) # 繫結充值
3. 更新選擇區域
當表格中選中區域發生改變時,更新當前選擇區域。
# 更新選擇區域
def update_selected(self):
list = self.tableWidget.selectedRanges()
for temp in list:
self.delete_f = temp.topRow()
self.delete_t = temp.bottomRow()
4. 便捷修改記錄
獲取當前選中行列,更新當前行列中的資料。
# 修改表資訊
def update_tableWidget(self):
# print(self.tableWidget.selectedItems()==None)
# print("x: " + str(self.tableWidget.selectedIndexes()[0].row()) + ", y: " + str(self.tableWidget.selectedIndexes()[0].column()))
# print("請求修改資訊")
if self.query_flag == 1:
return
i = self.tableWidget.currentIndex().row()
j = self.tableWidget.currentIndex().column()
lable = ['學號', '姓名', '性別', '學院', '專業', '手機號', '餘額']
# print(self.tableWidget.item(i,0).text(),lable[j],self.tableWidget.item(i,j).text())
DataUpdate(self.tableWidget.item(i, 0).text(), lable[j], self.tableWidget.item(i, j).text())
5. 更新標記 & 發射訊號
當表格中有元素被按下就更新查詢標記,防止查詢bug。另外兩個訊號是用來彈出視窗的。
# 更新標誌
def update_flag(self):
# print("flag")
self.query_flag = 0
# 批量插入按鈕發射訊號
def batch_button_signal(self):
self.batch_signal.emit() # 發射訊號
# 插入按鈕發射訊號
def insert_button_signal(self):
self.insert_signal.emit() # 發射訊號
6. 單個刪除 & 批量刪除
單個選擇刪除和批量刪除二者通過當前選擇行列來判斷是哪一種。同時刪除之前會彈出訊息框來確認是否刪除。批量刪除的實現是通過檢查檢視核取方塊的選擇狀態來實現批量刪除的。
# 批量刪除
def delete2(self):
if self.delete_f == -1 and self.delete_t == -1:
# QMessageBox.warning(self, "失敗", "請框選需要刪除的記錄!")
return False
for i in range(self.delete_f,self.delete_t + 1):
DeleteData(str(self.tableWidget.item(i, 0).text()))
self.query()
QMessageBox.information(self, "資訊", "刪除記錄成功!")
self.delete_t = -1
self.delete_f = -1
return True
# 刪除確認
def deleteConfirm(self):
message_box = QMessageBox()
message_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
message_box.setWindowTitle("提示")
message_box.setText("確認刪除?")
message_box.setWindowIcon(QIcon('logo.png'))
yes = message_box.button(QMessageBox.Yes)
yes.clicked.connect(self.delete) # 點選此按鈕則退出程式
message_box.exec()
# 刪除按鈕發射訊號
def delete(self):
if self.delete2():
return
flag = 0
for i in range(0, self.tableWidget.rowCount()):
if self.check_list[i].checkState() == 2:
flag = 1
DeleteData(str(self.tableWidget.item(i, 0).text()))
if flag == 1:
self.query()
QMessageBox.information(self, "提示", "刪除記錄成功!")
self.delete_t = -1
self.delete_f = -1
else:
QMessageBox.critical(self, "失敗", "請勾選需要刪除的記錄!")
7. 下拉框元素更新
# 下拉框增加元素
def update_ComboBox(self):
coll = self.comboBox_college.currentText()
self.comboBox_major.clear()
if coll == "計算機學院":
self.comboBox_major.addItems(["物聯網工程", "電腦科學與技術", "軟體工程", "通訊工程", "資訊保安"])
elif coll == "機械學院":
self.comboBox_major.addItems(["機械電子工程", "測控技術與儀器", "機械設計製造", "工業設計"])
elif coll == "外國語學院":
self.comboBox_major.addItems(["英語", "俄語", "日語", "法語", "西班牙語"])
8. 模糊查詢
通過獲取編輯框和下拉框的資料來進行查詢,通過輸入的欄位來改變sql語句進行模糊查詢。
# 模糊查詢
def query(self):
self.query_flag = 1
id = self.lineEdit_id.text()
name = self.lineEdit_name.text()
sex = self.comboBox_sex.currentText()
coll = self.comboBox_college.currentText()
major = self.comboBox_major.currentText()
number = self.lineEdit_phonenumber.text()
result = informationInput(id, name, sex, coll, major, number)
self.check_list.clear()
for i in range(0, result.__len__()):
# 下面六行用於生成居中的checkbox,不知道有沒有別的好方法
ck = QCheckBox()
self.check_list.append(ck)
# 呼叫資料庫
self.tableWidget.setRowCount(result.__len__())
self.tableWidget.setColumnCount(8)
self.tableWidget.setHorizontalHeaderLabels(['學號', '姓名', '性別', '學院', '專業', '手機號', '餘額', '選擇'])
self.tableWidget.setColumnWidth(0, 200)
self.tableWidget.setColumnWidth(1, 100)
self.tableWidget.setColumnWidth(2, 50)
self.tableWidget.setColumnWidth(3, 160)
self.tableWidget.setColumnWidth(4, 160)
self.tableWidget.setColumnWidth(5, 150)
self.tableWidget.setColumnWidth(6, 120)
self.tableWidget.setColumnWidth(7, 87)
for i in range(0, self.tableWidget.rowCount()):
self.tableWidget.setRowHeight(i, 44)
lable1 = ['學號', '姓名', '性別', '學院', '專業', '手機號', '餘額', '選擇']
for i in range(result.__len__()):
temp = result[i]
for j in range(0, lable1.__len__()):
if j < 7:
if temp[lable1[j]] is not None:
self.tableWidget.setItem(i, j, QTableWidgetItem(str(temp[lable1[j]])))
else:
self.tableWidget.setItem(i, j, QTableWidgetItem(" "))
else:
h = QHBoxLayout()
h.setAlignment(Qt.AlignCenter)
h.addWidget(self.check_list[i])
w = QWidget()
w.setLayout(h)
self.tableWidget.setCellWidget(i, j, w)
9. 更新交易記錄
根據輸入欄位模糊查詢交易記錄。
# 更新交易記錄
def upadate_tableWidget2(self):
id2 = self.lineEdit_id_2.text()
name2 = self.lineEdit_name_2.text()
type2 = self.comboBox_sex_2.currentText()
result = TransactionRecords(id2, name2, type2)
# 呼叫資料庫
lable1 = ['學號', '姓名', '消費型別', '消費時間', '金額變動', '餘額']
self.tableWidget_2.setRowCount(result.__len__())
self.tableWidget_2.setColumnCount(6)
self.tableWidget_2.setHorizontalHeaderLabels(lable1)
self.tableWidget_2.setColumnWidth(0, 200)
self.tableWidget_2.setColumnWidth(1, 150)
self.tableWidget_2.setColumnWidth(2, 100)
self.tableWidget_2.setColumnWidth(3, 300)
self.tableWidget_2.setColumnWidth(4, 138)
self.tableWidget_2.setColumnWidth(5, 138)
for i in range(0, self.tableWidget_2.rowCount()):
self.tableWidget_2.setRowHeight(i, 45)
for i in range(result.__len__()):
temp = result[i]
for j in range(0, lable1.__len__()):
if temp[j] is not None:
if j == 4:
money = str(temp[j])
if money[0] != '-':
money = "+ " + money
else:
money = "- " + money[1:]
self.tableWidget_2.setItem(i, 4, QTableWidgetItem(money))
else:
self.tableWidget_2.setItem(i, j, QTableWidgetItem(str(temp[j])))
else:
self.tableWidget_2.setItem(i, j, QTableWidgetItem(" "))
10. 充值
通過學號和充值金額進行更新資料。
# 充值
def top_up(self):
username = self.top_up_id.text()
money = self.top_up_money.text()
result = Recharge(money, username)
if result == 0:
QMessageBox.warning(self, "錯誤", "請輸入有效學號!")
self.top_up_id.setText('')
elif result == 1:
QMessageBox.warning(self, "錯誤", "請輸入正確金額!")
self.top_up_money.setText('')
else:
QMessageBox.information(self, "成功", "充值成功!")
self.top_up_id.setText('')
self.top_up_money.setText('')
五、單條插入視窗(InsertWindow.py)
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QIcon
from PyQt5.QtWidgets import *
from Insert_UI import Ui_InsertWindow
from Functions import *
class InsertWindow(QMainWindow, Ui_InsertWindow):
inserted_signal = pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('校園一卡通管理系統') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
# self.setWindowIcon(QIcon('1.jpg')) # 設定視窗圖示
# self.setStyleSheet('QWidget{background-color:%s}' % QColor(222, 222, 222).name()) # 設定視窗背景色
self.setWindowOpacity(1) # 設定整個計算器視窗的透明度
# ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 工作列圖示
self.comboBox_sex.addItems([" ", "男", "女"])
self.comboBox_college.addItems([" ", "計算機學院", "機械學院", "外國語學院"])
self.comboBox_major.addItems([" ", "物聯網工程", "電腦科學與技術", "軟體工程", "通訊工程", "資訊保安"])
# self.show()
# 按鈕繫結
self.pushButton_insert.clicked.connect(self.insert) # 插入事件
self.comboBox_college.activated.connect(self.update_ComboBox)
# 下拉框增加元素
def update_ComboBox(self):
coll = self.comboBox_college.currentText()
self.comboBox_major.clear()
if coll == "計算機學院":
self.comboBox_major.addItems(["物聯網工程", "電腦科學與技術", "軟體工程", "通訊工程", "資訊保安"])
elif coll == "機械學院":
self.comboBox_major.addItems(["機械電子工程", "測控技術與儀器", "機械設計製造", "工業設計"])
elif coll == "外國語學院":
self.comboBox_major.addItems(["英語", "俄語", "日語", "法語", "西班牙語"])
def insert(self):
# 資料庫互動
id = self.lineEdit_id.text()
name = self.lineEdit_name.text()
sex = self.comboBox_sex.currentText()
coll = self.comboBox_college.currentText()
major = self.comboBox_major.currentText()
number = self.lineEdit_phonenumber.text()
Imformation(id, name, sex, coll, major, number)
self.inserted_signal.emit()
QMessageBox.information(self, "成功", "插入記錄成功!")
pass
六、批量匯入視窗(BatchInsertedWindow.py)
import os
from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import ctypes
import time
from PyQt5.QtWidgets import QLineEdit, QMessageBox, QWidget
from BatchInserted_UI import Ui_BatchInsertedWindow
class BatchInsertedWindow(QtWidgets.QMainWindow, Ui_BatchInsertedWindow):
step = 0
first = 0
last = 0
number = 1
def __init__(self):
super().__init__()
self.setupUi(self)
self.setWindowTitle('校園一卡通管理系統') # 設定視窗標題
self.setWindowIcon(QIcon('logo.png')) # 設定視窗圖示
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") # 工作列圖示
# 將訊號連線到對應槽函式
self.batch_insert_button.clicked.connect(self.BatchInsert)
# self.batch_insert_button.clicked.connect(self.timerEvent)
self.timer = QBasicTimer
self.pbar.setValue(self.step)
# 鍵盤登入
def keyPressEvent(self, event):
QWidget.keyPressEvent(self, event)
key = event.key()
if key == Qt.Key_Enter:
self.BatchInsert()
def BatchInsert(self):
path = self.insert_path.text()
self.first = self.lineEdit.text()
self.last = self.lineEdit_2.text()
self.StudentInformation(path, self.first, self.last)
def StudentInformation(self, path, start, last):
import pymysql
from openpyxl import load_workbook
from datetime import date, datetime
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
if path == "":
path = ".//student.xlsx"
if os.path.exists(path):
workbook = load_workbook(filename=path)
sheet1 = workbook["sheet1"]
if start == "":
start = 1
if last == "":
last = 1
start = int(start)
last = int(last)
self.step = 0
self.first = start
self.last = last
from builtins import str
list1 = []
# from builtins import range
for q in range(start, last + 1):
list1.append([])
# print(q)
for row in sheet1.iter_rows(min_row=q, max_row=q):
# print(row)
for cell in row:
# from builtins import str
string = str(cell.value)
# print(string)
# print(string)
list1[q - start].append(string)
# print(list1)
cnt = 0
for i in range(0, len(list1)):
date = list1[i]
# print(i, date)
# print(date)
str1 = ""
self.number = i + 1
for j in range(6):
str1 += "'" + date[j] + "',"
str1 = str1[:-1]
sql_str = "INSERT INTO 學生基本資訊(學號, 姓名, 性別, 學院, 專業, 手機號, 餘額) VALUES(%s,%s)" % (str1, int(date[6]))
try:
# 執行sql語句
db.ping(reconnect=True)
cursor.execute(sql_str)
db.commit()
cnt += 1
except Exception as e:
# 如果發生錯誤則回滾
print("修改失敗!")
print(e)
db.rollback()
# 關閉資料庫連線
db.close()
# print(len(list1))
self.step = self.number / (self.last + 1 - self.first) * 100
self.pbar.setValue(self.step)
if self.step == 100.0:
time.sleep(0.3)
text = '成功插入' + str(cnt) + '條記錄!'
QMessageBox.warning(self, "成功", text)
self.step = 0
self.pbar.setValue(self.step)
else:
QMessageBox.warning(self, "錯誤", "請輸入正確路徑!")
七、與資料庫互動的各種方法(Functions.py)
與資料庫進行增刪改查等操作的各種方法。
from datetime import datetime
from multiprocessing import connection
Cno = '0' # 用於最後的登出
# 註冊賬號密碼
# 對應引數分別是學號,密碼,密保
def register(studentNumber, password, SecretGuard):
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
ch = "select 學號 from 學生基本資訊 where 學號='%s'" % studentNumber
cursor.execute(ch)
ch1 = cursor.fetchone()
if ch1 == None:
print("學號輸入錯誤")
else:
sql = """INSERT INTO 註冊(學號,
密碼,密保)
VALUES ('%s', '%s', '%s')""" % (studentNumber, password, SecretGuard)
try:
# 執行sql語句
cursor.execute(sql)
# 提交到資料庫執行
db.commit()
except:
# 如果發生錯誤則回滾
db.rollback()
# 關閉資料庫連線
db.close()
else:
print("註冊成功!")
return
# 登入
# 需要對應的變數來存放登入的賬號
def load(studentNumber, password):
global Cno
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
cur = connection.cursor()
# pattern = re.compile()
sqlDL = "select 學號 from 註冊 where 註冊.學號='%s' and 註冊.密碼='%s'" % (studentNumber, password)
cur.execute(sqlDL)
jilu = cur.fetchone() # 登錄檔中沒有對應賬號和密碼
if jilu == None:
return False
elif jilu != None:
Cno = studentNumber
return True
# 資訊的錄入
# 對應引數分別是 學號 性別 姓名 學院 專業 手機號 餘額
def Imformation(studentNumber, name, gender, College, major, mobileNumber):
import pymysql
# 開啟資料庫連線
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
money = 100
lable = [studentNumber, name, gender, College, major, mobileNumber]
lable1 = ['學號', '姓名', '性別', '學院', '專業', '手機號']
str = '' # 初始化為空串
str1 = ''
flag = 0
for i in range(4, 6):
# print(i)
if lable[i] != '':
str1 += lable1[i] + ","
flag = 1
str += "'" + lable[i] + "',"
str = str[:-1]
str1 = str1[:-1]
# print(studentNumber)
# # SQL 插入語句
if flag == 0:
sql = "INSERT INTO 學生基本資訊(學號,姓名,性別,學院,餘額) VALUES('%s','%s','%s','%s',%s)" % (
studentNumber, name, gender, College, money)
else:
sql = "INSERT INTO 學生基本資訊(學號,姓名,性別,學院,%s,餘額) VALUES ('%s','%s','%s','%s',%s, %s)" % (
str1, studentNumber, name, gender, College, str, money)
try:
# 執行sql語句
print(sql)
cursor.execute(sql)
# 提交到資料庫執行
db.commit()
except:
# 如果發生錯誤則回滾
print("資訊錄入錯誤")
db.rollback()
# 關閉資料庫連線
db.close()
else:
print('資訊錄入成功')
return
# 對應引數是 屬性和具體的值 比如性別,男
def Check(fun, natural):
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
cur = connection.cursor()
if fun == '性別':
sqlJiaoYi = "select * from 交易記錄 where 性別='%s'" % (natural)
elif fun == '學號':
sqlJiaoYi = "select * from 交易記錄 where 學號='%s'" % (natural)
elif fun == '消費型別':
sqlJiaoYi = "select * from 交易記錄 where 消費型別='%s'" % (natural)
elif fun == '1':
sqlJiaoYi = "select * from 交易記錄"
cur.execute(sqlJiaoYi)
result = cur.fetchall()
for data in result:
print(data)
cur.close()
connection.close()
# Check('性別', '女')
# 充值校園卡 要改
# 對應引數是 錢數 學號 時間
def Recharge(money, nameNumber):
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
time = datetime.now()
ch = "select 學號 from 學生基本資訊 where 學號='%s'" % (nameNumber)
cursor.execute(ch) # 載入到資料庫中
ch1 = cursor.fetchone() # 將資料拿出來
if ch1 is None:
return 0
else:
sql1 = "select 學號,餘額 from 學生基本資訊 where 學號='%s'" % (nameNumber)
cursor.execute(sql1)
ch3 = cursor.fetchone()
print(ch3)
sql = "update 學生基本資訊 set 餘額=餘額+%s where 學號='%s'" % (money, nameNumber)
sql3 = "INSERT INTO 交易記錄(學號,消費型別,金額變動,消費時間,餘額) VALUES ('%s','充值',%s,'%s',%s)" % (ch3[0], money, time, ch3[1] + float(money))
print(sql)
print(sql3)
try:
# 執行sql語句
cursor.execute(sql)
# 提交到資料庫執行
db.commit()
cursor.execute(sql3)
db.commit()
return 2
except:
# 如果發生錯誤則回滾
db.rollback()
# 關閉資料庫連線
db.close()
return 1
# 修改資訊
# 對應引數是學號
def Exchange(name):
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
cur = connection.cursor()
secretGuard = input("請輸入密保:")
sqlXH = "select 密保 from 註冊 where 註冊.學號='%s'" % (name)
cur.execute(sqlXH)
jilu = cur.fetchone()
# for data in jilu:
if jilu == {'密保': secretGuard}:
NewpPassword = input("請輸入新密碼:")
sqlNewPassword = "update 註冊 set 密碼='%s' where 學號='%s'" % (NewpPassword, name)
print("修改成功")
elif jilu != {'密碼': secretGuard}:
print("密保錯誤")
Exchange(name)
cur.close()
connection.close()
# 基本資訊表的輸出
# 對應引數是要輸出的表 比如要輸出學生基本資訊 str=學生基本資訊
def inputInformation(str):
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
try:
cursor = connection.cursor()
sql = "select * from %s" % (str)
cursor.execute(sql)
result = cursor.fetchall()
# 資訊的輸出
for data in result:
print(data)
except Exception as e:
print("資訊輸入錯誤")
# 提示錯誤資訊
# print(e)
cursor.close()
connection.close()
return
# str = input("請輸入所要輸出的表的名字:")
# inputInformation(str)
# 登出賬號
def logOut():
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
sql = "delete from 學生基本資訊 where 學號='%s'" % Cno
sql1 = "delete from 註冊 where 學號='%s'" % Cno
sql2 = "delete from 交易記錄 where 學號='%s'" % Cno
try:
# 執行sql語句
cursor.execute(sql1)
# 提交到資料庫執行
db.commit()
cursor.execute(sql2)
db.commit()
cursor.execute(sql)
db.commit()
except:
# 如果發生錯誤則回滾
print("登出失敗!")
db.rollback()
# 關閉資料庫連線
db.close()
else:
print("登出成功!")
# 學生基本資訊查詢
def informationInput(studentNumber, name, gender, College, major, mobileNumber):
lable = [studentNumber, name, gender, College, major, mobileNumber]
lable1 = ['學號', '姓名', '性別', '學院', '專業', '手機號']
str = "" # 初始化為空串
flag = 0
for i in range(6):
if lable[i] != '':
flag = 1
# str += (lable1[i] + "='" + lable[i] + "' and ")
str += (lable1[i] + " LIKE '%" + lable[i] + "%' and ")
str = str[:-5]
# print(str)
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
try:
cursor = connection.cursor()
if flag == 0:
sql = "select * from 學生基本資訊"
else:
sql = "select * from 學生基本資訊 where %s" % str
cursor.execute(sql)
result = cursor.fetchall()
# 資訊的輸出
return result
except Exception as e:
print("資訊輸入錯誤")
# 提示錯誤資訊
print(e)
cursor.close()
connection.close()
def DataUpdate(studentNumber, attribute, val):
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
sql = "update 學生基本資訊 set %s='%s' where 學號='%s'" % (attribute, val, studentNumber)
print(sql)
try:
# 執行sql語句
cursor.execute(sql)
# 提交到資料庫執行
db.commit()
except:
# 如果發生錯誤則回滾
print("修改失敗!")
db.rollback()
# 關閉資料庫連線
db.close()
else:
print("修改成功!")
def DeleteData(studentNumber):
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
# print(studentNumber)
sql = "DELETE FROM 學生基本資訊 WHERE 學號='%s'" % (studentNumber)
sql1 = "DELETE FROM 交易記錄 WHERE 學號='%s'" % (studentNumber)
try:
# 執行sql語句
cursor.execute(sql1)
# 提交到資料庫執行
db.commit()
cursor.execute(sql)
# 提交到資料庫執行
db.commit()
except:
# 如果發生錯誤則回滾
print("刪除資訊失敗!")
# db.rollback()
# # 關閉資料庫連線
db.close()
else:
print("刪除成功!")
# 交易記錄輸出
def TransactionRecords(studentNumber, name, ConsumptionType):
lable = [studentNumber, name, ConsumptionType]
lable1 = ['學號', '姓名', '消費型別']
str = "" # 初始化為空串
flag = 0
for i in range(3):
if lable[i] != "":
flag = 1
if i == 0:
str += "學生基本資訊." + lable1[i] + " LIKE '%" + lable[i] + "%' and "
elif i == 1:
str += "學生基本資訊." + lable1[i] + " LIKE '%" + lable[i] + "%' and "
elif i == 2:
str += lable1[i] + " LIKE '%" + lable[i] + "%' and "
if str.__len__()>5:
str = str[:-5]
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon')
cur = connection.cursor()
if flag == 0:
sql = "select 學生基本資訊.學號,學生基本資訊.姓名,消費型別,消費時間,金額變動,交易記錄.餘額 from 學生基本資訊,交易記錄 where 學生基本資訊.學號=交易記錄.學號"
else:
sql = "select 學生基本資訊.學號,學生基本資訊.姓名,消費型別,消費時間,金額變動,交易記錄.餘額 from 交易記錄,學生基本資訊 where 學生基本資訊.學號=交易記錄.學號 and %s" % str
# print(sql)
cur.execute(sql)
result = cur.fetchall()
# print(result)
# for data in result:
# print(data)
# 更改欄位
list = []
for i in range(result.__len__()):
temp = result[i]
list.append([])
for j in range(0, 6):
list[i].append(temp[j])
return list
cur.close()
connection.close()
# 檢查密保問題
def SecurityQuestion(name, secretGuard):
import pymysql.cursors
connection = pymysql.connect(host='localhost', port=3306, user='root', password='123456', db='onecartoon',
charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
cur = connection.cursor()
sqlXH = "select 密保 from 註冊 where 註冊.學號='%s'" % name
cur.execute(sqlXH)
jilu = cur.fetchone()
# for data in jilu:
cur.close()
connection.close()
if jilu == {'密保': secretGuard}:
return True
else:
return False
# 重置密碼
def ResetPassword(name, new_password):
import pymysql
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
sqlNewPassword = "update 註冊 set 密碼='%s' where 學號='%s'" % (new_password, name)
cursor.execute(sqlNewPassword) # 提交到資料庫執行
db.commit()
# 關閉資料庫連線
db.close()
def StudentInformation(path, start, last):
import pymysql
from openpyxl import load_workbook
from datetime import date, datetime
db = pymysql.connect("localhost", "root", "123456", "onecartoon")
# 使用cursor()方法獲取操作遊標
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
print("666")
if path == "":
path = "student.xlsx"
workbook = load_workbook(filename=".\\" + path)
# print(workbook.sheetnames)
sheet1 = workbook["sheet1"]
print("999")
if start == "":
start = 1
if last == "":
last = 1
start = int(start)
last = int(last)
print("start:" + str(start) + ", end:" + str(last))
list1 = []
# from builtins import range
for q in range(start, last+1):
list1.append([])
# print(q)
for row in sheet1.iter_rows(min_row=q, max_row=q):
# print(row)
for cell in row:
# from builtins import str
string = str(cell.value)
# print(string)
# print(string)
list1[q - start].append(string)
print(list1)
for i in range(0, len(list1)):
date = list1[i]
# print(i, date)
# print(date)
str1 = ""
for j in range(6):
str1 += "'" + date[j] + "',"
str1 = str1[:-1]
sql_str = "INSERT INTO 學生基本資訊(學號, 姓名, 性別, 學院, 專業, 手機號, 餘額) VALUES(%s,%s)" % (str1, int(date[6]))
print(sql_str)
try:
# 執行sql語句
db.ping(reconnect=True)
cursor.execute(sql_str)
db.commit()
except Exception as e:
# 如果發生錯誤則回滾
print("修改失敗!")
print(e)
db.rollback()
# 關閉資料庫連線
db.close()
———2020.12.27(羅涵)
THE END
相關文章
- jsp struts2 mysql實現的校園宿舍管理系統專案原始碼JSMySql原始碼
- # 計算機軟體技術實習日誌專案三(二) 迷宮專案實現計算機
- 駕校管理系統設計和實現
- 校園實驗室智慧管理系統開發
- 實驗專案四:圖書管理系統
- 智慧園區管理系統,園區管理軟體
- 佛盛龍體育館一卡通管理軟體系統
- 智慧校園人事管理系統原始碼(部分)原始碼
- 軟體專案管理實踐(#0)專案管理
- 【小米集團校園招聘】IoT 軟體專案經理
- [小米集團校園招聘] IoT 軟體專案經理
- 智慧園區管理系統園區軟體建設
- 工程管理系統原始碼-物料管理-工程專案管理系統-建築施工管理軟體原始碼專案管理
- 軟體系統的設計和實現
- 硬體銷售實施流程管理如何通過Zoho專案管理軟體實現?專案管理
- 智慧校園雲平臺電子班牌系統原始碼,智慧校園家校互通小程式原始碼原始碼
- 軟體專案管理之系統思考(轉)專案管理
- 智慧校園管理系統電子班牌原始碼帶微信小程式原始碼原始碼微信小程式
- 專欄文章 質量保障系統的落地實踐 (二) 專案管理設計 - 程式碼資訊設計專案管理
- 一個工程實踐專案的完整軟體系統設計方案
- Jsp struts實現的圖書館管理系統專案原始碼JS原始碼
- 軟體專案管理的實質(一)(轉)專案管理
- 軟體專案管理的實質(三)(轉)專案管理
- Java家校互聯智慧校園電子班牌管理系統原始碼Java原始碼
- 軟體設計師:計算機系統知識計算機
- 四位計算機的原理及其實現計算機
- 開源專案管理軟體有哪些?分享7個實用開源專案管理軟體專案管理
- C++實現管理系統的示例程式碼C++
- 小專案實施軟體配置管理探析
- 軟體專案管理 8.4.軟體專案質量計劃專案管理
- 專案管理體系實施方法論(轉)專案管理
- 校園網-真實的校園網路社群
- 檔案系統(四):FAT32檔案系統實現原理
- 如何實現專案管理專案管理
- 數字校園系統
- java版工程專案管理系統原始碼+系統管理+系統設定+專案管理Java專案管理原始碼
- Python實現機房管理軟體的檔案分發功能Python
- [WMS]倉儲管理系統專案紀實