2016-05-25 9 views
2

QDataWidgetMapperを使用して、ウィジェットとsqliteテーブルのデータをリンクしたいと考えています。データの行を指定するためのメソッドは、setCurrentIndex、toFirst、toLast、toNext、toPreviousの順番で行を順番に反復処理する場合にのみ動作するように見えるメソッドです。私は、必要なデータを含む行に直接ジャンプし、その行のハンドルを取得してマッパーに渡すことができるようにしたいと考えています。QDataWidgetMapper - pyqtのsqliteデータベース行のインデックスを検索します。

表の主キーは自動インクリメントの整数ですが、行を削除できるため、キーを使用して索引を推測できる保証はありません。

------------------------- 
|  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_() 

これは、タスクを達成しますが、設定するためのいくつかの直接的な方法で、効率的にデータベースを使用してより良い方法があるはずのように思えます数値インデックスではなくマッピングです。私はこれまでのところそれを見つけることができなかった。お使いのモデルはまだ、class Form()self.item_info_model.select()によって(移入され

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 

がalternativaly:

答えて

2

あなたは、モデルのrecord()方法を使用することができますそれは自動的に再選択されますsee documentation

+0

返信ありがとうございます。記録メソッドはSQLを削除しますが、目標私が実際に持っているのは、単一のステートメントを使用して必要な特定のレコードを選択できるようにすることです。その結果には、マッパーに直接渡すことのできる情報が含まれています。私の希望は、カウンタループをまったく使用しないことです。行ごとにクロールするループに応じて、大規模なデータベースでは毎回非常に遅くなるようです。 setFilterはいくらか約束があるように見えますが、私はまもなくそれを試してみましょう。 –

+0

私のeditied答えを参照してください –

+0

私はこれまでのところから、setFilterメソッドが私の望むように機能するように見えます。レコードメソッドを使用すると、SQLクエリを使用するよりもはるかにきれいに見えるので、これはポットに追加した素晴らしいボーナスです。本当にありがとう! –

関連する問題