PyQt5クイックスタート(8)PyQt5のデータベース操作
、SQLiteデータベース
1、SQLiteの紹介
SQLiteは、主に小型のデスクトップデータベースおよびデータベースアプリケーション、モバイルアプリケーションとして、自給、サーバーレス、ゼロコンフィギュレーション、トランザクションのSQLデータベースエンジンを達成するために、軽量データベースです。
公式サイト:
https://www.sqlite.org
2、SQLiteの共通操作
データベースファイルを作成し、作成後にSQLiteのコマンドラインモードを実行します。sqlite3 DatabaseName.db
すでにSQLiteのコマンドラインモードの実装に存在するViewデータベースファイル:.databases
データベースファイルが既に存在開き、データベースファイルが存在しない場合は、それが作成されます。sqlite3 DatabaseName.db
ビューを実行するにはSQLiteのコマンドラインモードでのヘルプ情報:.help
SQLiteのコマンドラインモードの実行中にテーブルを作成します。create table person(id integer primary key, name text);
テーブルにデータを挿入します。insert into person(id, name) values(1, "zhangsan");
クエリ:select * from person;
構造化照会表を:.schema person
3、SQLiteの管理ツール
SQLiteのデータベースを操作するインタフェースを提供し、いくつかのオープンソースのSQLiteとの良好なDBMS(データベース管理システム)があります。
SQLiteStudioは中国、無料のインストールをサポートする、コンパクト、強力な非常に専門的なSQLiteデータベース管理ソフトウェアです。
SQLiteStudioダウンロード:
https://sqlitestudio.pl/index.rvt?act=download
第二に、データベースへの接続
1、データベースドライバ
PyQtはでは、QSqlDatabaseクラスデータベースに接続し、データベースがQSqlDatabaseにデータベース接続を表すデータベース・インスタンスと対話する別のドライバで使用することができます。利用可能なデータベースドライバを次のように
QDB2 IBM DB2ドライバー
QMYSQL MySQLドライバ
QOCIするOracle Call Interfaceドライバ
(SQL ServerのMSを含む)QODBC ODBCドライバ
QPSQL PostgreSQLのドライバ
QSQLITE SQLite3のドライバ
QSQLITE2 SQLite2のドライバ
図2は、従来の方法をQSqlDatabase
次のようにQSqlDatabase一般的な方法は次のとおりです。
addDataBase:データベースのデータベース駆動型のタイプに設定し、接続
するデータベース名セット接続:setDataBaseNameメソッド
setHostName:ホスト名は、データベースのセットアップ
ユーザー名接続指定:setUserNameで
のsetPasswordを:接続オブジェクトのパスワードを設定し
ている場合、トランザクションをコミットします。コミット真の成功のリターンを実現。
ロールバック:ロールバック・データベースのトランザクションを
クローズ:データベース接続を閉じます
図3に示すように、データベース接続・インスタンス
import sys
from PyQt5.QtSql import QSqlDatabase
from PyQt5.QtCore import *
if __name__ == "__main__":
app = QCoreApplication(sys.argv)
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("/home/user/test.db")
if db.open():
print("open DB success.")
sys.exit(app.exec_())
第三に、SQL文を実行
QSqlQueryは、SQL文を実行し、操作する機能を持ってすることはDDLとDMLのSQLクエリの種類、実行可能なQSqlQuery.exec_()
SQL操作を実行するために使用します。
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtCore import *
def createDB():
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("/home/user/test.db")
if db.open():
query = QSqlQuery()
query.exec_("create table person(id int primary key, name varchar(20), address varchar(30))")
query.exec_("insert into person values(1, 'Bauer', 'beijing')")
query.exec_("insert into person values(2, 'Jack', 'shanghai')")
query.exec_("insert into person values(3, 'Alex', 'chengdu')")
db.close()
if __name__ == "__main__":
app = QCoreApplication(sys.argv)
createDB()
sys.exit(app.exec_())
他のデータベースが存在しない場合は、SQL文を実行した後、あなたはdb.closeデータベース接続を閉じる使用する必要があるデータベース接続のリソースが限られているので、あなたは、もはやデータベース接続を使用していないそうでない場合は、データベース接続のリソースは、最終的にプログラムを引き起こし、枯渇され、閉じていなければなりませんデータベースに正しく接続することができません。
あなたは、データベースとPyQtはウィンドウディスプレイにデータを読み込む必要がある場合、ウィンドウの初期化中にデータベースを開くウィンドウが閉じられたときに、接続を閉じることが必要です。
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("/home/user/test.db")
self.db.open()
def closeEvent(self, event):
self.db.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
第四に、データベースモデルビュー
QSqlTableModel Qtは、読み書き可能なデータ・モデルを提供し、高度なインタフェースであり、単一のテーブルに格納されたデータを読み出すため、テーブルがQTableViewデータベースに表示することができます。データベースに接続されている場合、テーブルには、設定可能なフィルタ条件を設定し、選択機能クエリ操作を使用するのSetFilter関数を使用して照会設けられています。SetEditerStrategy機能は、ポリシーエディタを設定するために使用することができ、次のようにポリシー設定を編集することができます:
QSqlTableModel.OnFieldChange:リアルタイムは、データベースに対するすべての変更を更新
QSqlTableModel.OnRowChangeを:ユーザが現在の行に更新されるように別の行を選択すると
QSqlTableModel.OnManuallSubmit:手動、自動ではなく、コミット提出します
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("/home/user/test.db")
self.db.open()
self.model = QSqlTableModel()
self.initializedModel()
self.tableView = QTableView()
self.tableView.setModel(self.model)
self.layout = QVBoxLayout()
addButton = QPushButton("add")
deleteButton = QPushButton("delete")
hLayout = QHBoxLayout()
hLayout.addWidget(addButton)
hLayout.addWidget(deleteButton)
self.layout.addWidget(self.tableView)
self.layout.addLayout(hLayout)
self.setLayout(self.layout)
self.resize(600, 400)
addButton.clicked.connect(self.onAddRow)
deleteButton.clicked.connect(self.onDeleteRow)
def initializedModel(self):
self.model.setTable("person")
self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
self.model.select()
self.model.setHeaderData(0, Qt.Horizontal, "ID")
self.model.setHeaderData(1, Qt.Horizontal, "Name")
self.model.setHeaderData(2, Qt.Horizontal, "Address")
def onAddRow(self):
self.model.insertRows(self.model.rowCount(), 1)
self.model.submit()
def onDeleteRow(self):
self.model.removeRow(self.tableView.currentIndex().row())
self.model.submit()
self.model.select()
def closeEvent(self, event):
self.db.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
第五に、ページングクエリ
1、データ準備
ページングは、学生情報学生テーブルのデータを使用して、あなたがテーブルを作成し、データを挿入するためのPythonを使用することができ、挿入するためにSQLiteのSQL文を使用してコマンドラインを使用することができます。
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("/home/user/test.db")
if not db.open():
return False
query = QSqlQuery()
query.exec_("create table student(id int primary key, name varchar(20), sex varchar(8), age int);")
query.exec_("insert into student values(1, 'Bauer', 'Man', 25)")
query.exec_("insert into student values(2, 'Alex', 'Man', 24)")
query.exec_("insert into student values(3, 'Mary', 'Female', 23)")
query.exec_("insert into student values(4, 'Jack', 'Man', 25)")
query.exec_("insert into student values(5, 'xiaoming', 'Man', 24)")
query.exec_("insert into student values(6, 'xiaohong', 'Female', 23)")
query.exec_("insert into student values(7, 'xiaowang', 'Man', 25)")
query.exec_("insert into student values(8, 'xiaozhang', 'Man', 25)")
query.exec_("insert into student values(9, 'xiaoli', 'Man', 25)")
query.exec_("insert into student values(10, 'xiaohan', 'Man', 25)")
2、タブ付きウィンドウ
タブ付きウィンドウには、ラベル、フロント、リア、ジャンプボタン等を含みます。
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class DataGrid(QWidget):
def __init__(self, parent=None):
super(DataGrid, self).__init__(parent)
# 数据库连接
self.db = None
# 布局管理器
self.layout = QVBoxLayout()
# 查询模型
self.queryModel = QSqlQueryModel()
# 表格视图
self.tableView = QTableView()
self.tableView.setModel(self.queryModel)
#
self.totalPageLabel = QLabel()
self.currentPageLabel = QLabel()
self.switchPageLineEdit = QLineEdit()
self.prevButton = QPushButton("Prev")
self.nextButton = QPushButton("Next")
self.switchPageButton = QPushButton("Switch")
self.currentPage = 0
self.totalPage = 0
self.totalRecordCount = 0
self.pageRecordCount = 5
def initUI(self):
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.layout.addWidget(self.tableView)
hLayout = QHBoxLayout()
hLayout.addWidget(self.prevButton)
hLayout.addWidget(self.nextButton)
hLayout.addWidget(QLabel("跳转到"))
self.switchPageLineEdit.setFixedWidth(40)
hLayout.addWidget(self.switchPageLineEdit)
hLayout.addWidget(QLabel("页"))
hLayout.addWidget(self.switchPageButton)
hLayout.addWidget(QLabel("当前页:"))
hLayout.addWidget(self.currentPageLabel)
hLayout.addWidget(QLabel("总页数:"))
hLayout.addWidget(self.totalPageLabel)
hLayout.addStretch(1)
self.layout.addLayout(hLayout)
self.setLayout(self.layout)
self.setWindowTitle("DataGrid")
self.resize(600, 300)
def closeEvent(self, event):
self.db.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = DataGrid()
window.initUI()
window.show()
sys.exit(app.exec_())
3、ページネーションクエリの実装
学生は、データベース・テーブルを読み込み、テーブルデータモデルの初期化。
import sys
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel, QSqlQueryModel
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import re
class DataGrid(QWidget):
def __init__(self, parent=None):
super(DataGrid, self).__init__(parent)
# 声明数据库连接
self.db = None
# 布局管理器
self.layout = QVBoxLayout()
# 查询模型
self.queryModel = QSqlQueryModel()
# 表格视图
self.tableView = QTableView()
self.tableView.setModel(self.queryModel)
#
self.totalPageLabel = QLabel()
self.currentPageLabel = QLabel()
self.switchPageLineEdit = QLineEdit()
self.prevButton = QPushButton("Prev")
self.nextButton = QPushButton("Next")
self.switchPageButton = QPushButton("Switch")
# 当前页
self.currentPage = 1
# 总页数
self.totalPage = None
# 总记录数
self.totalRecordCount = None
# 每页记录数
self.pageRecordCount = 4
self.initUI()
self.initializedModel()
self.setUpConnect()
self.updateStatus()
def initUI(self):
self.tableView.horizontalHeader().setStretchLastSection(True)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.layout.addWidget(self.tableView)
hLayout = QHBoxLayout()
hLayout.addWidget(self.prevButton)
hLayout.addWidget(self.nextButton)
hLayout.addWidget(QLabel("跳转到"))
self.switchPageLineEdit.setFixedWidth(40)
hLayout.addWidget(self.switchPageLineEdit)
hLayout.addWidget(QLabel("页"))
hLayout.addWidget(self.switchPageButton)
hLayout.addWidget(QLabel("当前页:"))
hLayout.addWidget(self.currentPageLabel)
hLayout.addWidget(QLabel("总页数:"))
hLayout.addWidget(self.totalPageLabel)
hLayout.addStretch(1)
self.layout.addLayout(hLayout)
self.setLayout(self.layout)
self.setWindowTitle("DataGrid")
self.resize(600, 300)
def setUpConnect(self):
self.prevButton.clicked.connect(self.onPrevPage)
self.nextButton.clicked.connect(self.onNextPage)
self.switchPageButton.clicked.connect(self.onSwitchPage)
def initializedModel(self):
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("/home/user/test.db")
if not self.db.open():
return False
self.queryModel.setHeaderData(0, Qt.Horizontal, "ID")
self.queryModel.setHeaderData(1, Qt.Horizontal, "Name")
self.queryModel.setHeaderData(2, Qt.Horizontal, "Sex")
self.queryModel.setHeaderData(3, Qt.Horizontal, "Age")
# 获取表的所有记录数
sql = "SELECT * FROM student"
self.queryModel.setQuery(sql, self.db)
self.totalRecordCount = self.queryModel.rowCount()
if self.totalRecordCount % self.pageRecordCount == 0:
self.totalPage = self.totalRecordCount / self.pageRecordCount
else:
self.totalPage = int(self.totalRecordCount / self.pageRecordCount) + 1
# 显示第1页
sql = "SELECT * FROM student limit %d,%d" % (0, self.pageRecordCount)
self.queryModel.setQuery(sql, self.db)
def onPrevPage(self):
self.currentPage -= 1
limitIndex = (self.currentPage - 1) * self.pageRecordCount
self.queryRecord(limitIndex)
self.updateStatus()
def onNextPage(self):
self.currentPage += 1
limitIndex = (self.currentPage - 1) * self.pageRecordCount
self.queryRecord(limitIndex)
self.updateStatus()
def onSwitchPage(self):
szText = self.switchPageLineEdit.text()
pattern = re.compile('^[0-9]+$')
match = pattern.match(szText)
if not match:
QMessageBox.information(self, "提示", "请输入数字.")
return
if szText == "":
QMessageBox.information(self, "提示", "请输入跳转页面.")
return
pageIndex = int(szText)
if pageIndex > self.totalPage or pageIndex < 1:
QMessageBox.information(self, "提示", "没有指定的页,清重新输入.")
return
limitIndex = (pageIndex - 1) * self.pageRecordCount
self.queryRecord(limitIndex)
self.currentPage = pageIndex
self.updateStatus()
# 根据分页查询记录
def queryRecord(self, limitIndex):
sql = "SELECT * FROM student limit %d,%d" % (limitIndex, self.pageRecordCount)
self.queryModel.setQuery(sql)
# 更新空间状态
def updateStatus(self):
self.currentPageLabel.setText(str(self.currentPage))
self.totalPageLabel.setText(str(self.totalPage))
if self.currentPage <= 1:
self.prevButton.setEnabled(False)
else:
self.prevButton.setEnabled(True)
if self.currentPage >= self.totalPage:
self.nextButton.setEnabled(False)
else:
self.nextButton.setEnabled(True)
# 界面关闭时关闭数据库连接
def closeEvent(self, event):
self.db.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = DataGrid()
window.show()
sys.exit(app.exec_())