[SOLVED] QAbstractProxyModel question
-
Hi Everyone,
I am using QSqlTableModel. I subclass flags(), data(), and setData(). I have a delegate and I am using QSqlRelationalDelegate. From my reading on model/view programming the delegate allows for fine resolution editing of the model where the proxy model should be used for data processing. I have combined data processing within the delegate which from my understanding would be where QAbstractProxyModel comes in. Does anyone have an example QAbstractProxyModel in PyQt? This is what I have so far if anyone has suggestions then I would love to hear how to make this better.
@
ID, IMPORT_SPATIAL, VECTOR_TYPE, DESCRIPTION, SPATIAL_WEIGHT, MAP_RATIO, NSSDA = range(7)
#class ProxyModel(QtGui.QProxyModel):def init(self, parent = None):
super(ProxyModel, self).init(parent)
class NaturalResourceDelegate(QtSql.QSqlRelationalDelegate):
'''this is the delegate class'''
signal = QtCore.pyqtSignal(QtCore.QModelIndex)
def init(self,database = None, table = None, parent=None):
super(NaturalResourceDelegate, self).init(parent)
self._table = table
self._dbfname = databasedef createEditor(self, parent, option, index): column = index.column() if column == DESCRIPTION: editor = QtGui.QLineEdit(parent) editor.returnPressed.connect(self.commitAndCloseEditor) return editor elif column == IMPORT_SPATIAL: button = QtGui.QPushButton("select Spatial Data", parent) self.file_browser = importgtlf.ImportGTLF(database = self._dbfname, parent = None) if self.file_browser.exec_(): return button elif column == SPATIAL_WEIGHT: combo = QtGui.QComboBox(parent) index_path = index.model().index(index.row(), IMPORT_SPATIAL) path = index.model().data(index_path, role = QtCore.Qt.DisplayRole).toString() print path if path != '': field_list = arcpy.ListFields(str(path), '', ["Double", "Interger", "String", "Single"] ) for field in field_list: if not field.required: combo.addItem(field.name) return combo elif column == MAP_RATIO: combo = QtGui.QComboBox(parent) query = QtSql.QSqlQuery(self._dbfname) query.prepare("SELECT scale FROM nssda_accuracy;") query.exec_() count = 0 while query.next(): map_scale = query.value(0).toString() combo.addItem(map_scale) return combo else: return QtSql.QSqlRelationalDelegate.createEditor(self, parent, option, index) def commitAndCloseEditor(self): '''Commit the data after the user hits enter and then close the editor. ''' editor = self.sender() if isinstance(editor, (QtGui.QTextEdit, QtGui.QLineEdit)): self.commitData.emit(editor) self.closeEditor.emit(editor, QtSql.QSqlRelationalDelegate.NoHint) def setEditorData(self, editor, index): column = index.column() text = index.model().data(index, QtCore.Qt.DisplayRole).toString() if column == DESCRIPTION: editor.setText(text) elif column == IMPORT_SPATIAL: editor.setText(text) elif column == SPATIAL_WEIGHT: i = editor.findText(text) if i == -1: i = 0 editor.setCurrentIndex(i) elif column == MAP_RATIO: i = editor.findText(text) if i == -1: i = 0 editor.setCurrentIndex(i) else: QtSql.QSqlRelationalDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index): column = index.column() if column == DESCRIPTION: model.setData(index, QtCore.QVariant(editor.text())) elif column == IMPORT_SPATIAL: model.setData(index, self.file_browser.path, role=QtCore.Qt.EditRole) path_index = model.index(index.row(), 1) path = model.data(path_index, role = QtCore.Qt.DisplayRole).toString() path_index = model.index(index.row(), VECTOR_TYPE) if path != '': desc = arcpy.Describe(str(self.file_browser.path)) model.setData(path_index, desc.shapeType, role=QtCore.Qt.EditRole) #else: # print str(self.file_browser.path) # print editor # model.setData(path_index, editor, role= QtCore.Qt.EditRole) elif column == SPATIAL_WEIGHT: text = editor.currentText() model.setData(index, QtCore.QVariant(text)) elif column == MAP_RATIO: text = editor.currentText() model.setData(index, QtCore.QVariant(text)) query = QtSql.QSqlQuery(self._dbfname) query.prepare("SELECT rmse FROM nssda_accuracy WHERE scale = '%s'" % (text)) query.exec_() while query.next(): rmse = query.value(0).toString() nssda_index = model.index(index.row(), NSSDA) model.setData(nssda_index, rmse, role= QtCore.Qt.EditRole) else: QtSql.QSqlRelationalDelegate.setModelData(self, editor, model, index)
@
Thank you for your help and patience.
Luke
-
Hi,
What processing are your thinking about ?
-
Under setData method I set two columns data from the same column. Is that right or should I be using QAbstractProxyModel for this? Here I set the map ratio column, but I also set nssda from what the user selects for map ratio. That just seemed like a backwards way of doing it but maybe not.
elif column == MAP_RATIO:
text = editor.currentText()
model.setData(index, QtCore.QVariant(text))
query = QtSql.QSqlQuery(self.dbfname)
query.prepare("SELECT rmse FROM nssda_accuracy WHERE scale = '%s'" % (text))
query.exec()
while query.next():
rmse = query.value(0).toString()
nssda_index = model.index(index.row(), NSSDA)
model.setData(nssda_index, rmse, role= QtCore.Qt.EditRole) -
Under setData method I set two columns data from the same column. Is that right or should I be using QAbstractProxyModel for this? Here I set the map ratio column, but I also set nssda from what the user selects for map ratio. That just seemed like a backwards way of doing it but maybe not.
@
elif column == MAP_RATIO:
text = editor.currentText()
model.setData(index, QtCore.QVariant(text))
query = QtSql.QSqlQuery(self.dbfname)
query.prepare("SELECT rmse FROM nssda_accuracy WHERE scale = '%s'" % (text))
query.exec()
while query.next():
rmse = query.value(0).toString()
nssda_index = model.index(index.row(), NSSDA)
model.setData(nssda_index, rmse, role= QtCore.Qt.EditRole)@
-
Did you mean setModelData ?
If so, there's nothing specifically wrong with that. The question is: Is the second column also editable ?
-
Yes sorry I meant setModelData. And the second column is not editable in the flags. I guess I thought QAbstractProxyModel was the better model/view approach. Thank you for your help SGaist.
-
Then another question would be: should it really be stored in the model or generated on the fly based on the value of the MAP_RATIO column ?
-
Hmmm you bring up a valid point. I guess it does not matter whether I calculate the nssda value on the fly or query a database table. I would like to store that value in the model and the sqlite table though. So I would think either way would work. Unless you think I am wrong?
-
Well, this is more of a database design decision. If each value of map_ratio has a corresponding nssda value then you should have a table for that and point your current table to that pair. So if for any reason the nssda value would change. You don't have to reanalyze your complete database to ensure that each value is updated.