1

A work-in-progress plugin's dialog window contains a rolodex which allows the user to cycle through a timeseries of data; updating the relative memory layers geometries with each new time selection.

The script below is called upon when cycling to a new time selection. Even though it updates the layer's geometry without problems, the layer's attribute table (if open) is updated with 'ERROR' for all of the reloaded field values. If the table is closed and reopened after each successive timeseries change, the field value updates are successful.

Is there a means of auto-updating a memory layers constantly opened attribute table based on user interaction?

        updates = []
        trackLayer.startEditing()
        for groupIdx, group in enumerate(newPathGroups):
            for pathIdx,path in enumerate(group):
                feature = QgsFeature()
                feature.setGeometry(QgsGeometry.fromPolyline(path))
                feature.setAttributes([self.groupNames[groupIdx][0],str(groupIdx+1),\
                                       trackingRange, feature.geometry().length()])
                trackProvider.addFeatures([feature])
        trackLayer.commitChanges()
        trackLayer.reload()
        trackLayer.updateFields()

UPDATE:

Is there possibly a inverse of the following function, allowing a checksum to see if existing table is open, and if so - remove and reload?

enter image description here

Although I would much rather possibly access an existing open attribute table model, and refresh the data source if possible...

1
  • *** Would there be any means to establish a QFileWatcher reference to a memory layer (counter intuitive ...) ?
    – Katalpa
    Sep 20, 2015 at 16:58

1 Answer 1

1

A backdoor of sorts - but the following code (dirtily) accesses the existing attribute table instance, checks the header values against know header for layer in question, then upon authentication - removes the attribute table, and reopens after updating memory layers geometry contents.

Is this reasonable?

    trackLayer = ftools_utils.getMapLayerByName(unicode('Particle_Tracks'))
    if trackLayer:
        # check for open attribute table relative to tracklayer
        dockWindows = self.iface.mainWindow().findChildren(QtGui.QTableView)
        for window in dockWindows:
            if window.objectName()=='mTableView':
                tableModel = window.model().sourceModel()
                trackingTable = False
                headerCheck = ['GroupName','GroupNum','TimeRange','TrackLength']
                for headIdx,header in enumerate(headerCheck):
                    if tableModel.headerData(0,Qt.Horizontal,Qt.DisplayRole): trackingTable = True
                    else: trackingTable = False
                # removes table parent, effectivly eleminating table object
                if trackingTable:
                    window.parent().parent().parent().setParent(None)

        #remove existing tracks
        trackLayer.selectAll()
        trackProvider = trackLayer.dataProvider()
        trackProvider.deleteFeatures(trackLayer.selectedFeaturesIds())
        trackLayer.removeSelection()

        # build new tracks
        trackingRange = self.TimeCombo.currentText().replace("\n"," ")
        trackLayer.startEditing()
        for groupIdx, group in enumerate(newPathGroups):
            for pathIdx,path in enumerate(group):
                feature = QgsFeature()
                feature.setGeometry(QgsGeometry.fromPolyline(path))
                feature.setAttributes([self.groupNames[groupIdx][0],str(groupIdx+1),\
                                       trackingRange, feature.geometry().length()])
                trackProvider.addFeatures([feature])
        trackLayer.commitChanges()
        trackLayer.reload()
        trackLayer.updateFields()
        try:
           # if tracking attribute table was open, reopen with refreshed data
            if trackingTable:
                self.iface.showAttributeTable(trackLayer)
        except: pass

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.