Python+PyQt5實(shí)現(xiàn)數(shù)據(jù)庫表格動(dòng)態(tài)增刪改
題目描述
本次實(shí)驗(yàn)為連接數(shù)據(jù)庫的實(shí)驗(yàn),并對(duì)數(shù)據(jù)庫進(jìn)行一些簡(jiǎn)單的操作,要實(shí)現(xiàn)的基本功能如下所示,要能連接并展現(xiàn)數(shù)據(jù)庫里的數(shù)據(jù),能夠?qū)崿F(xiàn)插入功能。

拓展;
- 實(shí)現(xiàn)按學(xué)號(hào)查找學(xué)生信息功能
- 實(shí)現(xiàn)清空數(shù)據(jù)功能
- 實(shí)現(xiàn)保存數(shù)據(jù)功能
- 實(shí)現(xiàn)右鍵菜單功能
解題思路/算法分析/問題及解決
本次實(shí)驗(yàn)可主要分為兩個(gè)部分,即數(shù)據(jù)庫連接操作部分和數(shù)據(jù)可視化操作界面部分。
數(shù)據(jù)庫連接部分采用python的pymysql庫對(duì)數(shù)據(jù)庫進(jìn)行連接操作。
數(shù)據(jù)可視化部分采用tableWidget控件進(jìn)行表格化的呈現(xiàn),并通過相應(yīng)的控件交互來實(shí)現(xiàn)功能。TableWidget的主要方法如下表所示:

實(shí)驗(yàn)代碼
數(shù)據(jù)庫連接
def db_connect(self):
self.db = pymysql.connect(host='localhost',
user='root',
password='Zwq197166',
port=3306,
database='test')
可視化界面操作部分
def inser_row(self, row, sid, name, sex, address):
sid_item = QTableWidgetItem(sid)
name_item = QTableWidgetItem(name)
sex_item = QTableWidgetItem(sex)
address_item = QTableWidgetItem(address)
self.tableWidget.insertRow(row)
self.tableWidget.setItem(row, 0, sid_item)
self.tableWidget.setItem(row, 1, name_item)
self.tableWidget.setItem(row, 2, sex_item)
self.tableWidget.setItem(row, 3, address_item)
@pyqtSlot()
def on_button_load_clicked(self):
if self.button_save.isEnabled():
r = QMessageBox.warning(self, "警告", "是否覆蓋當(dāng)前表格數(shù)據(jù)", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if r == QMessageBox.No:
return
self.tableWidget.setRowCount(0)
self.tableWidget.clearContents()
self.db_connect()
cursor = self.db.cursor()
sql = "select * from my_student;"
try:
cursor.execute(sql)
results = cursor.fetchall()
for (sid, name, sex,address) in results:
print(sid, name, sex, address)
row = self.tableWidget.rowCount()
# print(row)
self.inser_row(row, sid, name, sex, address)
data[sid] = [name, sex, address]
except:
print("unable to fetch data")
self.db.close()
self.button_save.setEnabled(True)
print("load")
@pyqtSlot()
def on_button_add_clicked(self):
di = inputDialog()
ok = di.exec_()
if not ok:
return
name = di.line_name.text()
sid = di.line_id.text()
sex = di.line_sex.text()
address = di.line_address.text()
print(name,sid)
print(type(address))
data[sid] = [name, sex, address]
self.inser_row(self.tableWidget.rowCount(), sid, name, sex, address)
print(data)
print("add")
# self.tableWidget.insertRow(self.tableWidget.rowCount()-1)
self.button_save.setEnabled(True)
@pyqtSlot()
def on_button_save_clicked(self):
print(data)
self.db_connect()
cursor = self.db.cursor()
try:
sql = "delete from my_student;"
cursor.execute(sql)
# self.db.commit()
for key, value in data.items():
sql = "insert into my_student(sid,name,sex,address) values('{sid}','{name}','{sex}','{address}');".format(sid=key, name=value[0], sex=value[1], address=value[2])
print(sql)
cursor.execute(sql)
self.db.commit()
self.db.close()
print("save")
self.button_save.setEnabled(False)
except:
QMessageBox.critical(self, "錯(cuò)誤", "數(shù)據(jù)格式有誤,請(qǐng)檢查")
@pyqtSlot()
def on_button_clear_clicked(self):
self.tableWidget.setRowCount(0)
self.tableWidget.clearContents()
data.clear()
self.line_id.clear()
self.button_save.setEnabled(True)
@pyqtSlot()
def on_button_search_clicked(self):
sid = self.line_id.text()
if not sid:
QMessageBox.critical(self, "警告", "請(qǐng)輸入一個(gè)學(xué)號(hào)!")
return
print(sid)
if sid in data:
search = INFO(sid)
search.exec_()
# print("search")
else:
QMessageBox.critical(self, "錯(cuò)誤", "該學(xué)號(hào)不存在!")
@pyqtSlot(QTableWidgetItem)
def on_tableWidget_itemActivated(self, item):
"""
按住Enter鍵時(shí),當(dāng)前選中的單元格向下
"""
row = self.tableWidget.row(item)
column = self.tableWidget.column(item)
totalrow = self.tableWidget.rowCount()
if row + 1 < totalrow:
row = self.tableWidget.row(item) + 1
self.tableWidget.setCurrentCell(row, column)
elif row + 2 == totalrow:
row = totalrow - 1
self.tableWidget.setCurrentCell(row, column)
@pyqtSlot(int, int)
def on_tableWidget_cellDoubleClicked(self, row, column):
id = self.tableWidget.item(row, 0).text()
di = inputDialog(sid=id)
ok = di.exec_()
if not ok:
return
name = di.line_name.text()
sid = di.line_id.text()
sex = di.line_sex.text()
address = di.line_address.text()
print("before:", id)
print("after:", sid)
self.tableWidget.item(row, 0).setText(sid)
self.tableWidget.item(row, 1).setText(name)
self.tableWidget.item(row, 2).setText(sex)
self.tableWidget.item(row, 3).setText(address)
data[sid] = [name, sex, address]
if id != sid:
del data[id]
self.button_save.setEnabled(True)
def closeEvent(self, event):
if self.button_save.isEnabled():
r = QMessageBox.warning(self, "警告", "你還有操作沒保存,現(xiàn)在保存下?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
if r == QMessageBox.No:
event.accept()
else:
event.ignore()
def context_menu(self,pos):
pop_menu = QMenu()
change_new_event = pop_menu.addAction("修改行")
delete_event = pop_menu.addAction("刪除行")
action = pop_menu.exec_(self.tableWidget.mapToGlobal(pos))
if action == change_new_event:
item = self.tableWidget.selectedItems()
row = item[0].row()
id = self.tableWidget.item(row, 0).text()
di = inputDialog(sid=id)
ok = di.exec_()
if not ok:
return
name = di.line_name.text()
sid = di.line_id.text()
sex = di.line_sex.text()
address = di.line_address.text()
print("before:",id)
print("after:",sid)
self.tableWidget.item(row, 0).setText(sid)
self.tableWidget.item(row, 1).setText(name)
self.tableWidget.item(row, 2).setText(sex)
self.tableWidget.item(row, 3).setText(address)
data[sid] = [name, sex, address]
if id != sid:
del data[id]
self.button_save.setEnabled(True)
elif action == delete_event:
r = QMessageBox.warning(self, "注意", "刪除可不能恢復(fù)了哦!", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if r == QMessageBox.No:
return
items = self.tableWidget.selectedItems()
if items:
selected_rows = []
for i in items:
row = i.row()
if row not in selected_rows:
selected_rows.append(row)
selected_rows = sorted(selected_rows, reverse=True)
for r in selected_rows:
sid = self.tableWidget.item(r, 0).text()
del data[sid]
self.tableWidget.removeRow(r)
self.button_save.setEnabled(True)
class inputDialog(QDialog, Ui_Dialog_input):
def __init__(self, sid=None):
super(inputDialog, self).__init__()
self.setupUi(self)
self.sid = sid
self.buttonBox.accepted.connect(self.check)
if sid:
self.line_id.setText(sid)
self.line_name.setText(data[sid][0])
self.line_sex.setText(data[sid][1])
self.line_address.setText(data[sid][2])
def check(self):
sid = self.line_id.text()
name = self.line_name.text()
if sid in data and self.sid not in data:
r = QMessageBox.warning(self, "警告", "該學(xué)號(hào)已存在!", QMessageBox.Ok)
return
if not sid:
r = QMessageBox.warning(self, "警告", "學(xué)號(hào)為必填項(xiàng)!", QMessageBox.Ok)
return
if not name:
r = QMessageBox.warning(self, "警告", "姓名為必填項(xiàng)!", QMessageBox.Ok)
return
self.accept()
# print('miss')
class INFO(QDialog, Ui_Dialog_info):
def __init__(self, id: str):
super(INFO, self).__init__()
self.setupUi(self)
self.line_id.setText(id)
self.line_name.setText(data[id][0])
self.line_sex.setText(data[id][1])
self.line_address.setText(data[id][2])
@pyqtSlot()
def on_button_confirm_clicked(self):
# print(1)
self.close()
運(yùn)行結(jié)果
導(dǎo)入數(shù)據(jù):

添加數(shù)據(jù):


清空數(shù)據(jù):

搜索數(shù)據(jù):

修改數(shù)據(jù):
雙擊修改

右鍵菜單修改:

刪除后:


保存數(shù)據(jù):

以上就是Python+PyQt5實(shí)現(xiàn)數(shù)據(jù)庫表格動(dòng)態(tài)增刪改的詳細(xì)內(nèi)容,更多關(guān)于Python PyQt5數(shù)據(jù)庫表格的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Python+PyQt5實(shí)現(xiàn)MySQL數(shù)據(jù)庫備份神器
- 基于PyQt5實(shí)現(xiàn)SqlServer數(shù)據(jù)庫表導(dǎo)出Excel表格小工具
- PyQt5?python?數(shù)據(jù)庫?表格動(dòng)態(tài)增刪改詳情
- Python GUI教程之在PyQt5中使用數(shù)據(jù)庫的方法
- pyqt5數(shù)據(jù)庫使用詳細(xì)教程(打包解決方案)
- python3+PyQt5 數(shù)據(jù)庫編程--增刪改實(shí)例
- python3+PyQt5使用數(shù)據(jù)庫表視圖
- python3+PyQt5使用數(shù)據(jù)庫窗口視圖
- PyQt5與數(shù)據(jù)庫交互的項(xiàng)目實(shí)踐
相關(guān)文章
Python的requests網(wǎng)絡(luò)編程包使用教程
requests包為Python擴(kuò)展了各種基于HTTP的網(wǎng)絡(luò)數(shù)據(jù)操作功能,包括各種請(qǐng)求與session和cookie等的追加,very強(qiáng)大,下面我們就來看一下Python的requests網(wǎng)絡(luò)編程包使用教程2016-07-07
Python企業(yè)編碼生成系統(tǒng)之主程序模塊設(shè)計(jì)詳解
這篇文章主要介紹了Python企業(yè)編碼生成系統(tǒng)之主程序模塊設(shè)計(jì),包括初始化、界面與邏輯實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下2019-07-07
500行代碼使用python寫個(gè)微信小游戲飛機(jī)大戰(zhàn)游戲
這篇文章主要介紹了500行代碼使用python寫個(gè)微信小游戲飛機(jī)大戰(zhàn)游戲,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10
Python docx庫刪除復(fù)制paragraph及行高設(shè)置圖片插入示例
這篇文章主要為大家介紹了Python docx庫刪除復(fù)制paragraph及行高設(shè)置圖片插入操作實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
在Python中處理字符串之ljust()方法的使用簡(jiǎn)介
這篇文章主要介紹了在Python中處理字符串之ljust()方法的使用,是Python學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-05-05
Django查找網(wǎng)站項(xiàng)目根目錄和對(duì)正則表達(dá)式的支持
這篇文章主要介紹了Django查找網(wǎng)站項(xiàng)目根目錄和對(duì)正則表達(dá)式的支持,僅供參考,需要的朋友可以參考下2015-07-07
Python tkinter的grid布局及Text動(dòng)態(tài)顯示方法
今天小編就為大家分享一篇Python tkinter的grid布局及Text動(dòng)態(tài)顯示方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10

