一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

 文炳春秋 2020-07-17


本文根據(jù)一個(gè)項(xiàng)目實(shí)例,記錄分享一下python將數(shù)據(jù)庫(kù)的內(nèi)容提取顯示到程序界面的過程及相關(guān)設(shè)置,探索python操作數(shù)據(jù)庫(kù)的用法。主要分享內(nèi)容:

  • 1、顯示數(shù)據(jù)庫(kù)內(nèi)容。

  • 2、修改數(shù)據(jù)庫(kù)內(nèi)容。

  • 3、表格控件指定滑塊位置。

  • 4、自定義右鍵菜單。

使用環(huán)境:python3.7 + Mysql5 +PyQt5

針對(duì)人群:初學(xué)者或有資料查閱需求者,資深人士勿噴,敬請(qǐng)?zhí)岢鰧氋F意見,本人虛心接受。

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

前期準(zhǔn)備:

1、創(chuàng)建軟件界面

2、與數(shù)據(jù)庫(kù)建立連接

1、創(chuàng)建軟件界面:

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

上圖為使用PyQt5相關(guān)模塊創(chuàng)建的工程造價(jià)系統(tǒng)界面,使用的模塊及功能:

  1. 1、QMainWindow模塊:繪制帶菜單、工具欄、狀態(tài)欄的整體框架。

  1. 2、QTreeWidget模塊:繪制左側(cè)導(dǎo)航欄。

  1. 3、QTableWidgetItem模塊:繪制中間用于顯示數(shù)據(jù)的表格。

  1. 4、QComboBox, QPushButton模塊:繪制下拉框、按鈕控件。

  1. 5、QSplitter模塊:設(shè)置各種控件的擺放組合方式,可鼠標(biāo)拖動(dòng)調(diào)整窗口大小。

  1. 6、QMessageBox模塊:設(shè)置交互彈框。

具體界面繪制過程不是本文重點(diǎn),暫不詳述。

2、與數(shù)據(jù)庫(kù)建立連接

要建立與數(shù)據(jù)庫(kù)的連接,首先得有具體的數(shù)據(jù)庫(kù),本案例在本機(jī)用mysql建立自己的數(shù)據(jù)庫(kù),然后再與軟件項(xiàng)目進(jìn)行連接。

2.1、自建數(shù)據(jù)庫(kù)

下載安裝好Mysql后,建議再裝一個(gè)可視化工具,我用的Navicat for Mysql,感覺不錯(cuò)。界面見下圖:

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

在這個(gè)工具界面下,可以很方便的創(chuàng)建修改數(shù)據(jù)表。有了工具后,接下來(lái)就是關(guān)鍵的填入數(shù)據(jù)。很多時(shí)候,客戶或者我們自己的數(shù)據(jù)是放在excel里的,我們可以通過Navicat 的導(dǎo)入向?qū)?,很方便的將excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù):

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

跟著向?qū)?,只需?jiǎn)單幾步就可完成數(shù)據(jù)導(dǎo)入。

2.2、連接數(shù)據(jù)庫(kù)

導(dǎo)入pymysql庫(kù),將庫(kù)的連接等功能寫入自建的類。本案通過讀取.cfg配置文件(有關(guān)配置文件的知識(shí),可參見python開發(fā)項(xiàng)目,不得不了解的.cfg配置文件),獲得連接庫(kù)需用到的5個(gè)參數(shù),在_init_初始類屬性時(shí),建立連接,代碼如下:

import pymysql
from configparser import ConfigParser

class MysqlDb():
def __init__(self):
self.cp = ConfigParser()
self.cp.read('source/sql_config.cfg')
host = self.cp.get('sql_connect', 'host')
port = int(self.cp.get('sql_connect', 'port'))
user = self.cp.get('sql_connect', 'user')
passwd = self.cp.get('sql_connect', 'passwd')
db = self.cp.get('sql_connect', 'db')
self.conn = pymysql.connect(host=host,
port=port,
user=user,
passwd=passwd,
db=db)
self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

其中,sql_config.cfg文件內(nèi)容為:

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

若不用配置文件,直接把5個(gè)參數(shù)寫在程序里也可以,代碼如下,貌似更簡(jiǎn)單:

class MysqlDb():
def __init__(self):
self.conn = pymysql.connect(host=‘127.0.0.1’,
port=3306,
user=‘root’,
passwd=‘771222’,
db=‘1’)
self.cur = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

一、顯示數(shù)據(jù)庫(kù)內(nèi)容

功能:在軟件界面,點(diǎn)擊左側(cè)導(dǎo)航欄,找到數(shù)據(jù)庫(kù)中與展開項(xiàng)對(duì)應(yīng)的表,將數(shù)據(jù)顯示在中間表格里。若目標(biāo)表不存在,提示創(chuàng)建。

實(shí)現(xiàn)步驟:

創(chuàng)建導(dǎo)航欄; → 點(diǎn)擊導(dǎo)航欄,獲取表名; → 查詢數(shù)據(jù)庫(kù),找到表,顯示內(nèi)容

具體過程:

1、用樹形控件創(chuàng)建導(dǎo)航欄,數(shù)據(jù)來(lái)源為數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)里導(dǎo)航欄數(shù)據(jù)源樣式為:

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

用代碼手動(dòng)逐條輸入是不可接受的,根據(jù)第一列數(shù)據(jù)長(zhǎng)度特點(diǎn),采用下面的批量創(chuàng)建方式,其中fl為傳遞的參數(shù),意思是“路基”或者其他專業(yè)。

def set_tree(self, fl):
qd_lj = MysqlDb().select_db('SELECT * FROM 清單' + fl) # 通過自建的Mysqlbd類的select_db函數(shù),得到數(shù)據(jù)庫(kù)里的目標(biāo)表
root = QTreeWidgetItem(self.tree)
root.setText(0, fl)
root.setIcon(0, QIcon(r'source\3.png'))
for i in range(0, len(qd_lj)):
bm = qd_lj[i]['編碼']
mc = qd_lj[i]['名稱']
if (len(bm) == 4):
root1 = QTreeWidgetItem(root)
root1.setText(0, mc)
root1.setText(1, bm)
elif (len(bm) == 7):
root2 = QTreeWidgetItem(root1)
root2.setText(0, mc)
root2.setText(1, bm)
elif (len(bm) == 10):
root3 = QTreeWidgetItem(root2)
root3.setText(0, mc)
root3.setText(1, bm)
elif (len(bm) == 13):
root4 = QTreeWidgetItem(root3)
root4.setText(0, mc)
root4.setText(1, bm)
elif (len(bm) == 16):
root5 = QTreeWidgetItem(root4)
root5.setText(0, mc)
root5.setText(1, bm)
elif (len(bm) == 19):
root6 = QTreeWidgetItem(root5)
root6.setText(0, mc)
root6.setText(1, bm)
elif (len(bm) == 22):
root7 = QTreeWidgetItem(root6)
root7.setText(0, mc)
root7.setText(1, bm)
else:
pass
self.tree.expandAll() # 設(shè)置樹形構(gòu)件全部展開
self.item = root # 自定義設(shè)置初始選中根條目

2、設(shè)置點(diǎn)擊樹形控件條目的信號(hào)槽函數(shù),將數(shù)據(jù)庫(kù)表內(nèi)容提取后顯示在表格控件。

self.tree.itemClicked.connect(self.showtreesql)

設(shè)置左鍵單擊導(dǎo)航欄時(shí),觸發(fā)函數(shù)showtreesql()。具體獲取數(shù)據(jù)功能在函數(shù)里設(shè)置。

def showtreesql(self, item):  # 單擊樹形節(jié)點(diǎn),將數(shù)據(jù)庫(kù)內(nèi)容顯示在表里
self.inputtable.clearContents() #清空中間的表格控件
self.inputtable.setRowCount(0) # 初始表格控件
self.item = item # 單擊導(dǎo)航欄時(shí),信號(hào)槽自動(dòng)帶當(dāng)前點(diǎn)擊節(jié)點(diǎn)信息參數(shù)item
if not item.child(0): # 判斷如果該節(jié)點(diǎn)沒有子節(jié)點(diǎn),即單擊的為最底層節(jié)點(diǎn),非子節(jié)點(diǎn)無(wú)對(duì)應(yīng)表格
self.decxcomb3.setDisabled(False)
self.select_item = "n" + item.text(1).replace('-', '') # 根據(jù)該節(jié)點(diǎn)編碼,得到對(duì)應(yīng)表格名稱
if self.decxcomb3.findText(self.select_item) == -1:
self.decxcomb3.addItem(self.select_item)
self.decxcomb3.setCurrentText(self.select_item) # 將表格名稱顯示在下拉框控件里
if self.table_exists(MysqlDb(),
self.select_item): # 查詢數(shù)據(jù)庫(kù),判斷是否存在對(duì)應(yīng)的表,
self.inputtable.setRowCount(1)
self.sql_to_input(self.select_item, self.inputtable) #如果存在表,查詢數(shù)據(jù)庫(kù),將數(shù)據(jù)讀取到表格
else:
# self.decxcomb3.isEnabled()
self.decxcomb3.setDisabled(True)

3、讀取數(shù)據(jù)庫(kù)內(nèi)容到表格的功能函數(shù)代碼:

def sql_to_input(self, sql_tabel, inputtable):
data = MysqlDb().select_db('SELECT * FROM ' + sql_tabel)
if data:
inputtable.setRowCount(len(data))
for i in range(len(data)):
inputtable.setItem(i, 0, QTableWidgetItem(data[i]['定額編號(hào)']))
inputtable.setItem(i, 1, QTableWidgetItem(data[i]['定額名稱']))
inputtable.setItem(i, 2, QTableWidgetItem(data[i]['單位']))
inputtable.setItem(i, 3, QTableWidgetItem(data[i]['數(shù)量']))
# print('數(shù)據(jù)庫(kù)寫入已完成”')
else:
# print('源表為空表,不執(zhí)行寫入操作')
pass

判斷數(shù)據(jù)庫(kù)是否存在某表的函數(shù)塊:

def table_exists(self, sql, table_name):  # 這個(gè)函數(shù)用來(lái)判斷數(shù)據(jù)庫(kù)是否含某表
tables = sql.select_db('SHOW TABLES') # 得到數(shù)據(jù)庫(kù)里的所有表名,
tabels_list = []
for i in tables:
n = i['Tables_in_1']
tabels_list.append(n)
if table_name in tabels_list:
return 1
else:
return 0

4、左鍵雙擊導(dǎo)航欄時(shí),觸發(fā)信號(hào)槽,當(dāng)不存在目標(biāo)表時(shí),提示創(chuàng)建新表:

def edittreesql(self, item):  # 雙擊樹形節(jié)點(diǎn),將新建數(shù)據(jù)庫(kù)表
if not item.child(0): # 判斷該節(jié)點(diǎn)沒有子節(jié)點(diǎn)
self.select_item = "n" + item.text(1).replace('-', '') # 記錄該節(jié)點(diǎn)編碼
self.decxcomb3.addItem(self.select_item)
self.decxcomb3.setCurrentText(self.select_item)
if self.table_exists(MysqlDb(), self.select_item): # 判斷是否存在本節(jié)點(diǎn)為名的表
# 判斷結(jié)果存在,將內(nèi)容顯示在表格控件里
self.inputtable.clearContents()
self.sql_to_input(self.select_item, self.inputtable)
else:
if QMessageBox.information(self, "創(chuàng)建定額表",
"即將為本清單創(chuàng)建定額輸入表:" + self.select_item,
QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
MysqlDb().biuldtabel(self.select_item) # 若沒有則在數(shù)據(jù)庫(kù)新建一個(gè)表,
self.inputtable.clearContents()
self.inputtable.setRowCount(1)
print('已創(chuàng)建表:', self.select_item)

二、修改數(shù)據(jù)庫(kù)內(nèi)容

1、設(shè)置保存按鈕

self.saveinput = QPushButton('保存到數(shù)據(jù)庫(kù)')
self.saveinput.clicked.connect(self.input_to_sql)

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

2、編寫保存按鈕點(diǎn)擊函數(shù)塊

def input_to_sql(self):
if self.decxcomb3.currentText():
MysqlDb().execute_db('DELETE FROM ' +
self.decxcomb3.currentText()) # 寫入數(shù)據(jù)庫(kù)前先清空原內(nèi)容
for i in range(self.inputtable.rowCount()):
v = []
for j in range(4):
if self.inputtable.item(i, j):
v.append(self.inputtable.item(i, j).text())
else:
v.append('')
insert_sql = 'INSERT INTO ' + self.decxcomb3.currentText(
) + " (定額編號(hào), 定額名稱, 單位, 數(shù)量) VALUES('" + v[0] + "', '" + v[
1] + "', '" + v[2] + "', '" + v[3] + "')"
MysqlDb().execute_db(insert_sql)

三、表格控件指定滑塊位置

設(shè)置下拉框選擇項(xiàng)目后,根據(jù)項(xiàng)目名讓中間下部的表格上下滑塊移動(dòng)至將當(dāng)前項(xiàng)目顯示在第一位:

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

設(shè)置信號(hào)槽:self.decxcomb2.currentTextChanged[str].connect(self.set_table2)

設(shè)置功能塊代碼:

def set_table2(self, fl):
for i in range(self.table2.rowCount()):
if self.table2.item(i, 0).text() == fl:
break
self.table2.verticalScrollBar().setValue(i)

四、自定義右鍵菜單

表格輸入時(shí),有時(shí)候難免存在需要插入行、刪除行的要求,最常見的就是下面的右鍵菜單處理了。

python操作數(shù)據(jù)庫(kù)項(xiàng)目實(shí)例分享

實(shí)現(xiàn)過程:

1)設(shè)置表格控件能響應(yīng)右鍵

self.inputtable.setContextMenuPolicy(Qt.CustomContextMenu)

2)設(shè)置右鍵信號(hào)槽函數(shù)

self.inputtable.customContextMenuRequested.connect(self.input_rightmenu)
def input_rightmenu(self): # 指定定額輸入表控件右鍵菜單
try:
self.contextMenu = QMenu()
self.actionA = self.contextMenu.addAction(u'刪除')
self.actionB = self.contextMenu.addAction(u'插入')
self.actionA.setIcon(QIcon(r"source\4.png"))
self.contextMenu.popup(QCursor.pos()) # 菜單顯示的位置
self.actionA.triggered.connect(self.deletcurrow)
self.actionB.triggered.connect(self.insertcurrow)
self.contextMenu.show()
except Exception as e:
print(e)

3)函數(shù)功能塊設(shè)置

def deletcurrow(self):
self.inputtable.removeRow(self.inputtable.currentRow())# 刪除當(dāng)前行

def insertcurrow(self):
self.inputtable.insertRow(self.inputtable.currentRow()) #在當(dāng)前行插入一行

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    五月激情五月天综合网| 白白操白白在线免费观看| 激情亚洲一区国产精品久久| 成人区人妻精品一区二区三区| 亚洲国产精品一区二区毛片| 日本免费熟女一区二区三区| 日韩丝袜诱惑一区二区| 国产亚洲视频香蕉一区| 九九热这里有精品20| 国产内射一级二级三级| 国产精欧美一区二区三区久久| 亚洲精品福利视频在线观看| 白白操白白在线免费观看| 午夜小视频成人免费看| 在线观看视频日韩成人| 一区二区三区日韩经典| 免费在线成人激情视频| 欧美亚洲综合另类色妞| 五月婷婷欧美中文字幕| 免费黄色一区二区三区| 国产在线一区二区免费| 婷婷九月在线中文字幕| 久草国产精品一区二区| 天海翼高清二区三区在线| 日韩毛片视频免费观看| 青青操成人免费在线视频| 黄色片一区二区三区高清| 国语久精品在视频在线观看| 99久久成人精品国产免费| 一二区不卡不卡在线观看| 国产综合欧美日韩在线精品| 五月天丁香亚洲综合网| 欧美日韩国产的另类视频| 日韩不卡一区二区视频| 日韩18一区二区三区| 欧美日韩一级aa大片| 日韩欧美一区二区亚洲| 亚洲一区二区精品久久av| 日本不卡一区视频欧美| 亚洲欧美一二区日韩高清在线| 国产亚洲系列91精品|