Python pyqt中sqlite数据库行的QDataWidgetMapper查找索引
我想使用QDataWidgetMapper将小部件与sqlite表中的数据链接起来。我发现用于指定数据行的方法似乎只有在按顺序一次遍历行时才有效:setCurrentIndex、toFirst、toLast、toNext、toPrevious。我希望能够直接跳转到包含所需数据的行,并检索该行的句柄,然后传递给映射器 表的主键是一个自动递增的整数,但由于可以删除行,因此不能保证可以使用该键猜测索引Python pyqt中sqlite数据库行的QDataWidgetMapper查找索引,python,qt,sqlite,pyqt,pyqt5,Python,Qt,Sqlite,Pyqt,Pyqt5,我想使用QDataWidgetMapper将小部件与sqlite表中的数据链接起来。我发现用于指定数据行的方法似乎只有在按顺序一次遍历行时才有效:setCurrentIndex、toFirst、toLast、toNext、toPrevious。我希望能够直接跳转到包含所需数据的行,并检索该行的句柄,然后传递给映射器 表的主键是一个自动递增的整数,但由于可以删除行,因此不能保证可以使用该键猜测索引 ------------------------- | item_info
-------------------------
| item_info |
|-----------------------|
|item_id | item_desc |
|---------|-------------|
|1 | item 1 |
|2 | item 2 |
|7 | blue item |
|15 | pink item | #ordered index is 3
-------------------------
我曾一度希望能够使用rowid返回表行的有序索引,但它看起来只返回主键,与行在表中的位置无关
我可以使用计数器遍历每一行,直到找到正确的一行,然后使用得到的计数器值作为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()
或者,您可以为您的模型设置过滤器:
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\u info\u model.select()在class表单()中填充
,因此将自动重新选择它感谢您的回复。record方法删除SQL,但我真正的目标是能够使用单个语句选择所需的特定记录,返回的结果包含可以直接传递给映射器的信息。我希望避免使用计数器loop完全正确。在我看来,对于大型数据库来说,依靠循环逐行爬行的速度会非常慢。setFilter似乎有一些希望,我将很快尝试一下。从我目前看到的情况来看,setFilter方法的性能似乎与我所希望的一样。使用record方法看起来也比usi干净得多不支持SQL查询,这是您添加到pot中的一个不错的奖励。非常感谢!