【发布时间】:2021-10-08 19:55:15
【问题描述】:
我有一个 QComboBox 从 QSqlRelationalTableModel 的关系模型填充并连接到 QDataWidgetMapper。
我在 QTableView 中选择一行,该行(记录)映射到 QLineEdit 和 QComboBox 小部件,然后我进行一些更改并保存。
如果我选择另一行并保存而不更改 QComboBox 值,则该值会更改并提交给模型。
我使用可编辑组合框不是为了将项目添加到列表中,而是在我有一个大列表而不是下拉组合框视图时使用完成功能
创建数据库:
import sqlite3
conn = sqlite3.connect('customers.db')
c = conn.cursor()
c.execute("PRAGMA foreign_keys=on;")
c.execute("""CREATE TABLE IF NOT EXISTS provinces (
ProvinceId TEXT PRIMARY KEY,
Name TEXT NOT NULL
)""")
c.execute("""CREATE TABLE IF NOT EXISTS customers (
CustomerId TEXT PRIMARY KEY,
Name TEXT NOT NULL,
ProvinceId TEXT,
FOREIGN KEY (ProvinceId) REFERENCES provinces (ProvinceId)
ON UPDATE CASCADE
ON DELETE RESTRICT
)""")
c.execute("INSERT INTO provinces VALUES ('N', 'Northern')")
c.execute("INSERT INTO provinces VALUES ('E', 'Eastern')")
c.execute("INSERT INTO provinces VALUES ('W', 'Western')")
c.execute("INSERT INTO provinces VALUES ('S', 'Southern')")
c.execute("INSERT INTO provinces VALUES ('C', 'Central')")
c.execute("INSERT INTO customers VALUES ('1', 'customer1', 'N')")
c.execute("INSERT INTO customers VALUES ('2', 'customer2', 'E')")
c.execute("INSERT INTO customers VALUES ('3', 'customer3', 'W')")
c.execute("INSERT INTO customers VALUES ('4', 'customer4', 'S')")
c.execute("INSERT INTO customers VALUES ('5', 'customer5', 'C')")
conn.commit()
conn.close()
这是窗口:
from PyQt5.QtWidgets import *
from PyQt5.QtSql import *
class Window(QWidget):
def __init__(self):
super().__init__()
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("customers.db")
self.db.open()
self.model = QSqlRelationalTableModel(self, self.db)
self.model.setTable("customers")
self.model.setRelation(2, QSqlRelation("provinces", "ProvinceId", "Name"))
self.model.setEditStrategy(QSqlTableModel.EditStrategy.OnManualSubmit)
self.model.select()
self.id = QLineEdit()
self.name = QLineEdit()
self.province = QComboBox()
# stuck here
self.province.setEditable(True)
self.province.setModel(self.model.relationModel(2))
self.province.setModelColumn(1)
self.province.setView(QTableView())
self.mapper = QDataWidgetMapper()
self.mapper.setItemDelegate(QSqlRelationalDelegate())
self.mapper.setModel(self.model)
self.mapper.addMapping(self.id, 0)
self.mapper.addMapping(self.name, 1)
self.mapper.addMapping(self.province, 2)
save = QPushButton("Save")
save.clicked.connect(self.submit)
self.tableView = QTableView()
self.tableView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
self.tableView.setSelectionBehavior(QTableView.SelectionBehavior.SelectRows)
self.tableView.setModel(self.model)
self.tableView.clicked.connect(lambda: self.mapper.setCurrentModelIndex(self.tableView.currentIndex()))
vBox = QVBoxLayout()
vBox.addWidget(self.id)
vBox.addWidget(self.name)
vBox.addWidget(self.province)
vBox.addSpacing(20)
vBox.addWidget(save)
vBox.addWidget(self.tableView)
self.setLayout(vBox)
self.mapper.toFirst()
def submit(self):
self.mapper.submit()
self.model.submitAll()
def main():
import sys
App = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(App.exec_())
if __name__ == '__main__':
main()
【问题讨论】:
-
你能不能解释清楚,有什么问题?您可以详细说明重现错误的过程,指出您希望获得的内容也很有用。可编辑的 QComboBox 的用途是什么?据了解,处于可编辑模式的 QComboBox 用于将项目添加到模型(在本例中为数据库),它这样做了,但问题(至少在查看数据库时)是没有创建有效的“provinceId”
-
@eyllanesc 我用更多细节更新帖子以产生问题。这个可重现的示例并不完全是我正在实施的,但它完全重现了我面临的问题。
-
我认为使用 QLineEdit + QCompleter 而不是可编辑的 QComboBox 更好,但我有一个问题:假设用户没有写整个单词,例如“Eas”或写一个不相关的单词例如“xxx”,当按下保存按钮时会发生什么?是否应该保存更改?
-
@eyllanesc 如果输入的单词不在列表中,则不应保存。
-
@embabi 你有什么版本的Qt?是否早于 5.12?
标签: python pyqt5 qcombobox qsqlrelationaltablemodel qdatawidgetmapper