如何将可编辑的QComboBox链接到数据库

时间:2017-09-19 05:56:41

标签: python pyside qcombobox qsqldatabase

我正在使用Pyside创建一个从sqlite数据库中提取的组合框。用户可以选择其中一个现有项目或添加新项目。用户看到项目名称(称为“param”),但我需要从数据库访问项目ID。因此,有两个步骤:

阅读项目:我能够从数据库中读取数据,但在访问幕后项目ID时无法显示项目名称。

添加项目:我是否需要检测组合框中的更改,然后使用SQL插入命令或模型是否为我处理此问题?

此代码从数据库中读取但无法正确显示:

param_model = QSqlQueryModel()
param_model.setQuery("select id, param from partable order by param")
param_model.setHeaderData(0, Qt.Horizontal,"id")
param_model.setHeaderData(1, Qt.Horizontal,"param")

param_view = QTableView()
param_view.setColumnHidden(0,True)

self.paramfield = QComboBox()
self.paramfield.adjustSize()
self.paramfield.setEditable(True)
self.paramfield.setModel(param_model)
self.paramfield.setView(param_view)

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。首先,您需要使用可编辑的QSqlTableModel,而不是QSqlQueryModel,它是只读的。其次,您不需要在组合框上设置标题或视图。第三,必须在组合框中设置正确的模型列才能显示适当的值。

关于添加项目的问题:只需要通过模型提交更改。然而,通常还希望找到添加的项目的id或索引(例如,为了重置当前索引)。如果对模型进行排序和/或允许重复输入,这可能有点棘手。

下面的演示脚本向您展示了如何处理上述所有问题:

import sys
from PySide import QtCore, QtGui, QtSql

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(':memory:')
        self.db.open()
        self.db.transaction()
        self.db.exec_(
            'CREATE TABLE partable'
            '(id INTEGER PRIMARY KEY, param TEXT NOT NULL)'
            )
        self.db.exec_("INSERT INTO partable VALUES(1, 'Red')")
        self.db.exec_("INSERT INTO partable VALUES(2, 'Blue')")
        self.db.exec_("INSERT INTO partable VALUES(3, 'Green')")
        self.db.exec_("INSERT INTO partable VALUES(4, 'Yellow')")
        self.db.commit()
        model = QtSql.QSqlTableModel(self)
        model.setTable('partable')
        column = model.fieldIndex('param')
        model.setSort(column, QtCore.Qt.AscendingOrder)
        model.select()
        self.combo = QtGui.QComboBox(self)
        self.combo.setEditable(True)
        self.combo.setModel(model)
        self.combo.setModelColumn(column)
        self.combo.lineEdit().returnPressed.connect(self.handleComboEdit)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.combo)

    def handleComboEdit(self):
        if self.combo.lineEdit().isModified():
            model = self.combo.model()
            model.submitAll()
            ID = model.query().lastInsertId()
            if ID is not None:
                index = model.match(
                    model.index(0, model.fieldIndex('id')),
                    QtCore.Qt.EditRole, ID, 1, QtCore.Qt.MatchExactly)[0]
                self.combo.setCurrentIndex(index.row())

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(800, 50, 200, 50)
    window.show()
    sys.exit(app.exec_())   

PS:以下是如何使用当前索引从组合框中获取id

model = self.combo.model()
index = self.combo.currentIndex()
ID = model.index(index, model.fieldIndex('id')).data()