我想使用QDataWidgetMapper将小部件与sqlite表中的数据链接起来。我发现用于指定数据行的方法似乎只有在一次一个地顺序遍历行时才起作用:setCurrentIndex,toFirst,toLast,toNext,toPrevious。我希望能够直接跳转到包含所需数据的行,并检索该行的句柄,然后传递给映射器。
表的主键是一个自动递增的整数,但由于可以删除行,因此无法保证可以使用键猜测索引。
-------------------------
| 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_()
这完成了任务,但似乎应该有一种更好的方式来有效地使用数据库,使用一些直接的方法来设置映射而不是数字索引。如果是这样的话,我到目前为止还是找不到它。
答案 0 :(得分:2)
您可以使用模型的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
alternativaly您可以为模型设置过滤器:
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()
,因此会自动重新选择machine epsilon