我有一个包含两个表good和category.
通过QSqlRelationalTableModel表格的可视化,用值good替换列来实现。Сategorycatnameid
按下按钮时btnAdd = QPushButton("&Добавить запись"),在数据库中实现了一条记录在一个表中good,填写时需要指明该记录属于哪个记录(以后会正常工作)。id categoryQSqlRelationalTableModel
如何代替self.line_edit_category QCombobox表格中的数据,category以便清楚用户输入的内容。
比如一个下拉列表,让用户不能输入错误的东西:
import sys
from PyQt5 import QtSql
from PyQt5.Qt import *
class Dialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle('Input Dialog')
self.line_edit_name = QLineEdit()
self.line_edit_quantity = QLineEdit()
self.line_edit_category = QLineEdit()
form_layout = QFormLayout()
form_layout.addRow('Name:', self.line_edit_name)
form_layout.addRow('quantity:', self.line_edit_quantity)
form_layout.addRow('category:', self.line_edit_category)
button_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout(self)
main_layout.addLayout(form_layout)
main_layout.addWidget(button_box)
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.createConnection()
self.fillTable() # !!!
self.createModel()
self.initUI()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
btnAdd = QPushButton("&Добавить запись")
btnAdd.clicked.connect(self.addRecord)
btnDel = QPushButton("&Удалить запись")
btnDel.clicked.connect(self.delRecord)
layout = QVBoxLayout(self.centralWidget)
layout.addWidget(self.view)
layout.addWidget(btnAdd)
layout.addWidget(btnDel)
def createConnection(self):
self.db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("test_1318914.db") # !!! .db
if not self.db.open():
print("Cannot establish a database connection")
return False
def fillTable(self):
self.db.transaction()
q = QtSql.QSqlQuery()
# vvvvvvvv
q.exec_("DROP TABLE IF EXISTS category;")
q.exec_("CREATE TABLE category (id INT PRIMARY KEY, catname TEXT);")
q.exec_("INSERT INTO category VALUES (1, 'Расходники');")
q.exec_("INSERT INTO category VALUES (2, 'Носители');")
# vvvv
q.exec_("DROP TABLE IF EXISTS good;")
q.exec_("CREATE TABLE good (Name TEXT, Quantity INT, Category INT);")
q.exec_("INSERT INTO good VALUES ('Барабан для принтера', 8, 1);")
q.exec_("INSERT INTO good VALUES ('Бумага для принтера', 3, 1);")
q.exec_("INSERT INTO good VALUES ('Дискета', 10, 2);")
self.db.commit()
def createModel(self):
self.model = QtSql.QSqlRelationalTableModel()
self.model.setTable("good")
self.model.setHeaderData(0, Qt.Horizontal, "Название")
self.model.setHeaderData(1, Qt.Horizontal, "Кол-во")
self.model.setHeaderData(2, Qt.Horizontal, "Категория")
self.set_relation()
self.model.select()
def initUI(self):
self.view = QTableView()
self.view.setModel(self.model)
self.view.setColumnWidth(0, 150)
mode = QAbstractItemView.SingleSelection
self.view.setSelectionMode(mode)
def closeEvent(self, event):
if (self.db.open()):
self.db.close()
def set_relation(self):
self.model.setRelation(2, QtSql.QSqlRelation(
"category",
"id",
"catname"
))
def addRecord(self):
inputDialog = Dialog()
rez = inputDialog.exec()
if not rez:
msg = QMessageBox.information(self, 'Внимание', 'Диалог сброшен.')
return
name = inputDialog.line_edit_name.text()
quantity = inputDialog.line_edit_quantity.text()
category = inputDialog.line_edit_category.text()
if (not name) or (not quantity) or (not category):
msg = QMessageBox.information(self,
'Внимание', 'Заполните пожалуйста все поля.')
return
r = self.model.record()
r.setValue(0, name)
r.setValue(1, int(quantity))
r.setValue(2, int(category))
self.model.insertRecord(-1, r)
self.model.select()
def delRecord(self):
row = self.view.currentIndex().row()
if row == -1:
msg = QMessageBox.information(self,
'Внимание', 'Выберите запись для удаления.')
return
name = self.model.record(row).value(0)
quantity = self.model.record(row).value(1)
category = self.model.record(row).value(2)
inputDialog = Dialog()
inputDialog.setWindowTitle('Удалить запись ???')
inputDialog.line_edit_name.setText(name)
inputDialog.line_edit_quantity.setText(str(quantity))
inputDialog.line_edit_category.setText(str(category))
rez = inputDialog.exec()
if not rez:
msg = QMessageBox.information(self, 'Внимание', 'Диалог сброшен.')
return
self.model.setRelation(2, QtSql.QSqlRelation())
self.model.select()
self.model.removeRow(row)
self.set_relation()
self.model.select()
msg = QMessageBox.information(self, 'Успех', 'Запись удалена.')
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Example()
w.setWindowTitle("QRelationalSqlTableModel")
w.resize(430, 250)
w.show()
sys.exit(app.exec_())

总的来说,决定已经来了 =) 逻辑如下:
我们创建了一个函数,该函数将从数据库
fill_combobox()中读取一个表category并返回一个格式为 ['1 Consumables', '2 Media'] 的列表,其中一个分隔符由空格分隔,以便稍后可以提取该数字以写入 id将列表传递给对话框构造函数并填充
QComboBox我们考虑文本
currentText,通过拆分我们将获取列表的第一个元素。用户感到满意和高兴 =))) 通过标记#<---的更改地点的代码