[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 = database

    def 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


  • Lifetime Qt Champion

    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)

    @


  • Lifetime Qt Champion

    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.


  • Lifetime Qt Champion

    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?


  • Lifetime Qt Champion

    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.