QDataWidgetMapper-在pyqt中查找sql​​ite数据库行的索引

QDataWidgetMapper-find index for sqlite database row in pyqt

我想使用 QDataWidgetMapper link 一个在 sqlite table 中包含数据的小部件。我找到的用于指定数据行的方法似乎只有在一次按顺序遍历行时才有效:setCurrentIndex、toFirst、toLast、toNext、toPrevious。我希望能够直接跳转到包含所需数据的行,并检索该行的句柄,然后传递给映射器。

table的主键是一个自动递增的整数,但由于可以删除行,因此不能保证可以使用该键猜出索引。

-------------------------
|     item_info         |
|-----------------------|
|item_id  |  item_desc  |
|---------|-------------|
|1        |  item 1     |
|2        |  item 2     |
|7        |  blue item  |
|15       |  pink item  | #ordered index is 3
-------------------------

我曾短暂地希望能够使用 rowid 来 return table 行的有序索引,但看起来只有 return 是主键而不是与行在 table.

中的位置概念相关

我可以使用计数器遍历每一行,直到找到正确的行,然后使用生成的计数器值作为 setCurrentIndex 的参数,但这似乎是一个糟糕的解决方案。这是一个示例,显示 item_id 15:

行中的 item_desc
import sys 
from PyQt5 import Qt,QtWidgets,QtSql

class Form(QtWidgets.QWidget):
    def __init__(self,parent=None):
        QtWidgets.QWidget.__init__(self,parent)
        self.line_edit=QtWidgets.QLineEdit()
        layout=QtWidgets.QVBoxLayout()
        layout.addWidget(self.line_edit)
        self.setLayout(layout)        

        db=QtSql.QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName("populated_db.db")
        db.open()

        self.item_info_model = QtSql.QSqlTableModel(self)
        self.item_info_model.setTable("item_info")
        self.item_info_model.select()

        self.item_info_mapper = Qt.QDataWidgetMapper(self)
        self.item_info_mapper.setSubmitPolicy(Qt.QDataWidgetMapper.ManualSubmit)
        self.item_info_mapper.setModel(self.item_info_model)

        self.item_info_mapper.addMapping(self.line_edit, 1) #establishes mapping between line edit and the second column of data


        self.show_description(15)

    def show_description(self,desired_item_id):
        ###### NOW HERE IS AN UGLY TECHNIQUE TO SEARCH ONE BY ONE UNTIL DESIRED ROW IS DISCOVERED ######
        i=0 #start counter
        success=False

        query=QtSql.QSqlQuery()
        query.exec("SELECT item_id FROM item_info")
        query.first()

        while not success:
            if query.value(0)==desired_item_id:
                success=True
                self.item_info_mapper.setCurrentIndex(i)
            else:
                i+=1
                query.next()

a=QtWidgets.QApplication(sys.argv)
form=Form()
form.show()
a.exec_()

这完成了任务,但似乎应该有更好的方法来有效地使用数据库,使用一些直接的方法来设置映射而不是数字索引。如果是这样的话,我到目前为止还找不到它。

您可以使用模型的record()方法:

def show_description(self,desired_item_id):
    for i in range(self.item_info_model.rowCount()):
        if self.item_info_model.record(i).value(0) == desired_item_id:  # the field can be defined by position or by name 
            self.item_info_mapper.setCurrentIndex(i)
            break

或者您可以为您的模型设置过滤器:

def show_description(self,desired_item_id):
    self.item_info_model.setFilter('item_id = {}'.format(desired_item_id))
    self.item_info_mapper.toFirst()

您的模型已经填充(由 self.item_info_model.select()class Form() 中填充,因此将自动重新选择它 see documentation