# QTableView Ui handeler (aka tableView)
# Initalize primary connections between [Data]<->[Proxy]<->[View]
# and commit fundamental tableView formating
def __init__(self, iface, fileName, parent=None):
super(CSVeditor, self).__init__(parent)
self.iface = iface
self.fileName = fileName
self.tableData = CSVModel(fileName)
self.proxyModel.setSourceModel(self.tableData)
self.proxyModel.setFilterKeyColumn(0)
self.tableView.setModel(self.proxyModel)
cellSelectionModel = self.tableView.selectionModel()
cellSelectionModel.selectionChanged.connect(self.selRange)
self.connect(self.proxyModel,QtCore.SIGNAL('dataChanged(QModelIndex,QModelIndex)'),self.shareChanges)
# create buttons and connections
self.pushButtonSave.setText("Save Changes")
self.pushButtonSave.clicked.connect(self.on_pushButtonSave_clicked)
self.pushButtonClose.setText("Exit")
self.pushButtonClose.clicked.connect(self.Cancel)
# implement read only parameters (column specific)
self.ReadOnly = ReadOnly(self.tableView)
self.tableView.setItemDelegateForColumn(0,self.ReadOnly)
# open Ui and populate based upon QgsLayer feature(s) selection
self.show()
self.selectedObjects()
self.iface.mapCanvas().selectionChanged.connect(self.selectedObjects)
# retrieve list of all selected objects on mapCanvas to proxy-filter displayed rows in CSV editor
def selectedObjects(self):
selectListIDs = []
editListIDs = []
editLayer = self.iface.activeLayer().name()
editLayer_Atrib = ftools_utils.getMapLayerByName(unicode("%s") % (editLayer))
totalFeatures = range(editLayer_Atrib.featureCount())
features = editLayer_Atrib.selectedFeatures()
for feature in features:
selectListIDs.append(list(feature.attributes())[0])
revisedSelection = "|".join([str(cellID) for cellID in selectListIDs])
self.proxyModel.setFilterRegExp('^('+str(revisedSelection)+')$')
print self.proxyModel.rowCount()
print self.tableData.rowCount(self)
# nessecary slot and signal functions
@QtCore.pyqtSlot()
def on_pushButtonSave_clicked(self):
self.tableData.saveIt()
def Cancel(self):
self.close()
# main startup
if __name__ == "__main__":
app.setApplicationName('CSV Editor')
main = CSVeditor(fileName)
main.show()
sys.exit(app.exec_())
#---------------------------------------------------------------------------------------------------
# readOnly column establishments in QtableView
def __init__(self, parent):
def createEditor(self, parent, option, index):
item.setReadOnly(True)
return item
def setEditorData(self, editor, index):
editor.blockSignals(True)
editor.setText(index.model().data(index))
editor.blockSignals(False)
def setModelData(self, editor, model, index):
model.setData(index, editor.text())
#---------------------------------------------------------------------------------------------------
# QTableModel data handeler (aka tableData)
activeRows = 1000000000000 #<=== this value is equivalent to len(rows) or ensuring that all rows are initially filtered via proxy
# load in csv data, and establish inital limiter on loaded row count (for efficency)
def __init__(self, fileName, parent=None):
super(CSVModel,self).__init__()
self.header = []
self.rows = []
self.fileName = fileName
with open(self.fileName, "rb") as fileInput:
for idx, row in enumerate(csv.reader(fileInput)):
headerIDx = 0
if idx is headerIDx:
self.header.append(row)
elif idx>headerIDx:
items = [field for field in row]
self.rows.append(items)
self.rowsLoaded = CSVModel.activeRows
# relative axis index counts
def rowCount(self,index):
if not self.rows:
return 0
if len(self.rows) <= self.rowsLoaded:
return len(self.rows)
else:
return self.rowsLoaded
def columnCount(self,index):
return len(self.header[0])
# extended data retrieval based upon Qtableview / proxyFilter demands (scrolling)
def canFetchMore(self,index):
if len(self.rows) > self.rowsLoaded:
return True
else:
return False
def fetchMore(self,index):
reminder = len(self.rows) - self.rowsLoaded
itemsToFetch = min(reminder,CSVModel.activeRows)
self.beginInsertRows(index,self.rowsLoaded,(self.rowsLoaded+itemsToFetch-1))
self.rowsLoaded += itemsToFetch
self.endInsertRows()
def addRow(self,row):
self.beginResetModel()
self.rows.append(row)
self.endResetModel()
# source value data for cell(s) in QtableView
def data(self,index,role):
if index.isValid() and role == Qt.DisplayRole:
return self.rows[index.row()][index.column()]
# establish header data
def headerData(self,section,orientation,role):
if role != Qt.DisplayRole:
return
if orientation == Qt.Vertical:
return int(section)
if orientation == Qt.Horizontal:
return self.header[0][section]
# write changes from QtableView and proxyFilter to (self) tableData
def setData(self, index, value, role):
if index.isValid() and role == Qt.EditRole:
self.rows[index.row()][index.column()]=str(value)
self.dataChanged.emit(index, index)
return True
return False
# distinguish capabilities of total cells in tableData model
def flags(self, index):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
# one toast & peanutbutter-jelly sandwitch please
def saveIt(self):
with open(self.fileName, "wb") as fileOutput:
writer = csv.writer(fileOutput)
writer.writerow(self.header[0])
for rowNumber in range(len(self.rows)):
fields = self.rows[rowNumber]
writer.writerow(fields)
# QTableView Ui handeler (aka tableView)
class CSVeditor(QtGui.QDialog, QtGui.QWidget):
# Initalize primary connections between [Data]<->[Proxy]<->[View]
# and commit fundamental tableView formating
def __init__(self, iface, fileName, parent=None):
super(CSVeditor, self).__init__(parent)
self.iface = iface
self.fileName = fileName
self.tableView = QtGui.QTableView(self)
self.tableData = CSVModel(fileName)
self.proxyModel = QtGui.QSortFilterProxyModel()
self.proxyModel.setSourceModel(self.tableData)
self.proxyModel.setFilterKeyColumn(0)
self.tableView.setModel(self.proxyModel)
cellSelectionModel = self.tableView.selectionModel()
cellSelectionModel.selectionChanged.connect(self.selRange)
self.connect(self.proxyModel,QtCore.SIGNAL('dataChanged(QModelIndex,QModelIndex)'),self.shareChanges)
# create buttons and connections
self.pushButtonSave = QtGui.QPushButton(self)
self.pushButtonSave.setText("Save Changes")
self.pushButtonSave.clicked.connect(self.on_pushButtonSave_clicked)
self.pushButtonClose = QtGui.QPushButton(self)
self.pushButtonClose.setText("Exit")
self.pushButtonClose.clicked.connect(self.Cancel)
# implement read only parameters (column specific)
self.ReadOnly = ReadOnly(self.tableView)
self.tableView.setItemDelegateForColumn(0,self.ReadOnly)
# open Ui and populate based upon QgsLayer feature(s) selection
self.show()
self.selectedObjects()
self.iface.mapCanvas().selectionChanged.connect(self.selectedObjects)
# retrieve list of all selected objects on mapCanvas to proxy-filter displayed rows in CSV editor
def selectedObjects(self):
selectListIDs = []
editListIDs = []
editLayer = self.iface.activeLayer().name()
editLayer_Atrib = ftools_utils.getMapLayerByName(unicode("%s") % (editLayer))
totalFeatures = range(editLayer_Atrib.featureCount())
features = editLayer_Atrib.selectedFeatures()
for feature in features:
selectListIDs.append(list(feature.attributes())[0])
revisedSelection = "|".join([str(cellID) for cellID in selectListIDs])
self.proxyModel.setFilterRegExp('^('+str(revisedSelection)+')$')
print self.proxyModel.rowCount()
print self.tableData.rowCount(self)
# nessecary slot and signal functions
@QtCore.pyqtSlot()
def on_pushButtonSave_clicked(self):
self.tableData.saveIt()
def Cancel(self):
self.close()
# main startup
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
app.setApplicationName('CSV Editor')
main = CSVeditor(fileName)
main.show()
sys.exit(app.exec_())
#---------------------------------------------------------------------------------------------------
# readOnly column establishments in QtableView
class ReadOnly(QtGui.QItemDelegate):
def __init__(self, parent):
QtGui.QItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
item = QtGui.QLineEdit(parent)
item.setReadOnly(True)
return item
def setEditorData(self, editor, index):
editor.blockSignals(True)
editor.setText(index.model().data(index))
editor.blockSignals(False)
def setModelData(self, editor, model, index):
model.setData(index, editor.text())
#---------------------------------------------------------------------------------------------------
# QTableModel data handeler (aka tableData)
class CSVModel(QtCore.QAbstractTableModel):
activeRows = 1000000000000 #<=== this value is equivalent to len(rows) or ensuring that all rows are initially filtered via proxy
# load in csv data, and establish inital limiter on loaded row count (for efficency)
def __init__(self, fileName, parent=None):
super(CSVModel,self).__init__()
self.header = []
self.rows = []
self.fileName = fileName
with open(self.fileName, "rb") as fileInput:
for idx, row in enumerate(csv.reader(fileInput)):
headerIDx = 0
if idx is headerIDx:
self.header.append(row)
elif idx>headerIDx:
items = [field for field in row]
self.rows.append(items)
self.rowsLoaded = CSVModel.activeRows
# relative axis index counts
def rowCount(self,index):
if not self.rows:
return 0
if len(self.rows) <= self.rowsLoaded:
return len(self.rows)
else:
return self.rowsLoaded
def columnCount(self,index):
return len(self.header[0])
# extended data retrieval based upon Qtableview / proxyFilter demands (scrolling)
def canFetchMore(self,index):
if len(self.rows) > self.rowsLoaded:
return True
else:
return False
def fetchMore(self,index):
reminder = len(self.rows) - self.rowsLoaded
itemsToFetch = min(reminder,CSVModel.activeRows)
self.beginInsertRows(index,self.rowsLoaded,(self.rowsLoaded+itemsToFetch-1))
self.rowsLoaded += itemsToFetch
self.endInsertRows()
def addRow(self,row):
self.beginResetModel()
self.rows.append(row)
self.endResetModel()
# source value data for cell(s) in QtableView
def data(self,index,role):
if index.isValid() and role == Qt.DisplayRole:
return self.rows[index.row()][index.column()]
# establish header data
def headerData(self,section,orientation,role):
if role != Qt.DisplayRole:
return
if orientation == Qt.Vertical:
return int(section)
if orientation == Qt.Horizontal:
return self.header[0][section]
# write changes from QtableView and proxyFilter to (self) tableData
def setData(self, index, value, role):
if index.isValid() and role == Qt.EditRole:
self.rows[index.row()][index.column()]=str(value)
self.dataChanged.emit(index, index)
return True
return False
# distinguish capabilities of total cells in tableData model
def flags(self, index):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
# one toast & peanutbutter-jelly sandwitch please
def saveIt(self):
with open(self.fileName, "wb") as fileOutput:
writer = csv.writer(fileOutput)
writer.writerow(self.header[0])
for rowNumber in range(len(self.rows)):
fields = self.rows[rowNumber]
writer.writerow(fields)
To copy to clipboard, switch view to plain text mode
Bookmarks