class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsEditorWidgetRegistry.initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() self.am.loadAttributes() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100 * i, 2 ^ i))) features.append(f) self.assertTrue(pr.addFeatures(features)) return layer def testLoad(self): self.assertEqual(self.am.rowCount(), 10) self.assertEqual(self.am.columnCount(), 2) def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) self.assertEqual(self.am.rowCount(), 9) self.layer.selectByIds([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() self.assertEqual(self.am.rowCount(), 5) def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200))) self.layer.addFeature(f) self.assertEqual(self.am.rowCount(), 11) def testRemoveColumns(self): self.assertTrue(self.layer.startEditing()) self.assertTrue(self.layer.deleteAttribute(1)) self.assertEqual(self.am.columnCount(), 1)
class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsEditorWidgetRegistry.initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() self.am.loadAttributes() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100 * i, 2 ^ i))) features.append(f) assert pr.addFeatures(features) return layer def testLoad(self): assert self.am.rowCount() == 10, self.am.rowCount() assert self.am.columnCount() == 2, self.am.columnCount() def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) assert self.am.rowCount() == 9, self.am.rowCount() self.layer.setSelectedFeatures([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() assert self.am.rowCount() == 5, self.am.rowCount() def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(100, 200))) self.layer.addFeature(f) assert self.am.rowCount() == 11, self.am.rowCount() def testRemoveColumns(self): assert self.layer.startEditing() assert self.layer.deleteAttribute(1) assert self.am.columnCount() == 1, self.am.columnCount()
class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100 * i, 2 ^ i))) features.append(f) self.assertTrue(pr.addFeatures(features)) return layer def testLoad(self): self.assertEqual(self.am.rowCount(), 10) self.assertEqual(self.am.columnCount(), 2) def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) self.assertEqual(self.am.rowCount(), 9) self.layer.selectByIds([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() self.assertEqual(self.am.rowCount(), 5) def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) self.layer.addFeature(f) self.assertEqual(self.am.rowCount(), 11) def testRemoveColumns(self): self.assertTrue(self.layer.startEditing()) self.assertTrue(self.layer.deleteAttribute(1)) self.assertEqual(self.am.columnCount(), 1) def testEdit(self): fid = 2 field_idx = 1 new_value = 333 # get the same feature from model and layer feature = self.layer.getFeature(fid) model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that feature from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) # change attribute value for a feature and commit self.layer.startEditing() self.layer.changeAttributeValue(fid, field_idx, new_value) self.layer.commitChanges() # check the feature in layer is good feature = self.layer.getFeature(fid) self.assertEqual(feature.attribute(field_idx), new_value) # get the same feature from model and layer model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that index from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx))
class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100 * i, 2 ^ i))) features.append(f) self.assertTrue(pr.addFeatures(features)) return layer def testLoad(self): self.assertEqual(self.am.rowCount(), 10) self.assertEqual(self.am.columnCount(), 2) def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) self.assertEqual(self.am.rowCount(), 9) self.layer.selectByIds([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() self.assertEqual(self.am.rowCount(), 5) def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) self.layer.addFeature(f) self.assertEqual(self.am.rowCount(), 11) def testRemoveColumns(self): self.assertTrue(self.layer.startEditing()) self.assertTrue(self.layer.deleteAttribute(1)) self.assertEqual(self.am.columnCount(), 1) def testEdit(self): fid = 2 field_idx = 1 new_value = 333 # get the same feature from model and layer feature = self.layer.getFeature(fid) model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that feature from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) # change attribute value for a feature and commit self.layer.startEditing() self.layer.changeAttributeValue(fid, field_idx, new_value) self.layer.commitChanges() # check the feature in layer is good feature = self.layer.getFeature(fid) self.assertEqual(feature.attribute(field_idx), new_value) # get the same feature from model and layer model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that index from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx))
class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100 * i, 2 ^ i))) features.append(f) self.assertTrue(pr.addFeatures(features)) return layer def testLoad(self): self.assertEqual(self.am.rowCount(), 10) self.assertEqual(self.am.columnCount(), 2) def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) self.assertEqual(self.am.rowCount(), 9) self.layer.selectByIds([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() self.assertEqual(self.am.rowCount(), 5) def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) self.layer.addFeature(f) self.assertEqual(self.am.rowCount(), 11) def testRemoveColumns(self): self.assertTrue(self.layer.startEditing()) self.assertTrue(self.layer.deleteAttribute(1)) self.assertEqual(self.am.columnCount(), 1) def testEdit(self): fid = 2 field_idx = 1 new_value = 333 # get the same feature from model and layer feature = self.layer.getFeature(fid) model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that feature from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) # change attribute value for a feature and commit self.layer.startEditing() self.layer.changeAttributeValue(fid, field_idx, new_value) self.layer.commitChanges() # check the feature in layer is good feature = self.layer.getFeature(fid) self.assertEqual(feature.attribute(field_idx), new_value) # get the same feature from model and layer model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that index from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) def testStyle(self): style_threshold = 2 color = QColor(133, 133, 133) style = QgsConditionalStyle() style.setRule(f'"fldint" <= {style_threshold}') style.setTextColor(color) self.layer.conditionalStyles().setRowStyles([style]) for f in self.layer.getFeatures(): model_index = self.am.idToIndex(f.id()) text_color = self.am.data(model_index, Qt.TextColorRole) if f['fldint'] <= style_threshold: self.assertEqual(text_color, color) else: self.assertIsNone(text_color) self.assertTrue(self.layer.startEditing()) feature1 = self.layer.getFeature(2) feature1['fldint'] = style_threshold + 1 feature2 = self.layer.getFeature(8) feature2['fldint'] = style_threshold self.assertTrue(self.layer.updateFeature(feature1)) self.assertTrue(self.layer.updateFeature(feature2)) self.assertTrue(self.layer.commitChanges()) for f in self.layer.getFeatures(): model_index = self.am.idToIndex(f.id()) text_color = self.am.data(model_index, Qt.TextColorRole) if f['fldint'] <= style_threshold: self.assertEqual(color, text_color, f'Feature {f.id()} should have color') else: self.assertIsNone(text_color, f'Feature {f.id()} should have no color') self.layer.conditionalStyles().setRowStyles([]) def testTransactionRollback(self): """Test issue https://github.com/qgis/QGIS/issues/48171#issuecomment-1132709901""" d = QTemporaryDir() path = d.path() source_fields = QgsFields() source_fields.append(QgsField('int', QVariant.Int)) vl = QgsMemoryProviderUtils.createMemoryLayer('test', source_fields) f = QgsFeature() f.setAttributes([1]) vl.dataProvider().addFeature(f) tmpfile = os.path.join(path, 'testTransactionRollback.sqlite') options = { 'driverName': 'SpatiaLite', 'layerName': 'test' } err = QgsVectorLayerExporter.exportLayer(vl, tmpfile, "ogr", vl.crs(), False, options) self.assertEqual(err[0], QgsVectorLayerExporter.NoError, 'unexpected import error {0}'.format(err)) vl = QgsVectorLayer( 'dbname=\'{}\' table="test" () sql='.format(tmpfile), 'test', 'spatialite') self.assertTrue(vl.isValid()) p = QgsProject.instance() p.setTransactionMode(Qgis.TransactionMode.AutomaticGroups) self.assertTrue(p.addMapLayer(vl)) cache = QgsVectorLayerCache(vl, 100) am = QgsAttributeTableModel(cache) am.loadLayer() self.assertEqual(am.rowCount(), 1) self.assertTrue(vl.startEditing()) vl.beginEditCommand('edit1') f = QgsFeature() f.setAttributes([2]) self.assertTrue(vl.addFeature(f)) self.assertEqual(am.rowCount(), 2) self.assertEqual(len([f for f in vl.getFeatures()]), 2) vl.endEditCommand() self.assertTrue(vl.rollBack()) self.assertEqual(len([f for f in vl.getFeatures()]), 1) self.assertEqual(am.rowCount(), 1)
class UploadImages: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'UploadImages_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = UploadImagesDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Upload Images') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'UploadImages') self.toolbar.setObjectName(u'UploadImages') self.dlg.pushButton.clicked.connect(self.selectOutputFile) self.dlg.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True) self.dlg.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.copyFiles) self.dlg.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.cancelAction) self.downloadOK = None def selectOutputFile(self): #filename = QFileDialog.getSaveFileName(self.dlg, "Selecione ","", '*.txt') filename = QFileDialog.getExistingDirectory(self.dlg, "Selecione ","") self.dlg.lineEdit.setText(filename) def cancelAction(self): if self.p is not None: self.p.kill() #pyqtRemoveInputHook() #pdb.set_trace() self.downloadOK = False self.dlg.reject() def dbInsertData(self): pass def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginVectorMenu( self.tr(u'&Task Manager'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('UploadImages', message) def copyFiles(self): #actlayer1 = qgis.utils.iface.activeLayer() #features1 = actlayer1.selectedFeatures() self.dlg.progressBar.setMaximum(len(self.features)) self.dlg.progressBar.setValue(0) msgBox = PyQt4.QtGui.QMessageBox() diretorioDestino = self.dlg.lineEdit.text() if(diretorioDestino): pass else: msgBox.setText("Selecione a Pasta de Destino!") msgBox.setStandardButtons(QMessageBox.Ok); msgBox.exec_() return #actlayer = qgis.utils.iface.activeLayer() index = self.modelt.index(0,0) contadorBarra = 0 for row in range(self.modelt.rowCount()): self.downloadArquivo(self.modelt.data(self.modelt.index(row,self.dlg.comboBoxCampos.currentIndex()), 0),diretorioDestino) contadorBarra += 1 self.dlg.progressBar.setValue(contadorBarra) #pyqtRemoveInputHook() #pdb.set_trace() if self.downloadOK is not False: self.downloadOK = True if self.downloadOK is True: msgBox.setText("Imagens Copiadas com Sucesso!") msgBox.setStandardButtons(QMessageBox.Ok); msgBox.exec_() self.dlg.accept() def downloadArquivo(self, caminhoArquivo, diretorioDestino): print("Inicio3") #caminhoArquivo = r'\\172.23.5.17\cotec\divabd\Mario\SIGRH.png' caminhoSalvar = caminhoArquivo[caminhoArquivo.find("\\indice_imagens\\"):] #caminhoSalvar = '\cotec\divabd\Mario\SIGRH.png' caminhoSalvar.replace("\\", "/") print("caminho 2 = "+caminhoArquivo) print("CaminhoSalvar"+caminhoSalvar) #nomeArquivo = caminhoArquivo #print("NomeArquivo="+nomeArquivo) nomeArquivo = os.path.basename(caminhoArquivo) print(caminhoArquivo) #pyqtRemoveInputHook() #pdb.set_trace() #if(os.path.isfile(diretorioDestino,nomeArquivo)) if "win" in _platform: #for generic use, test fullpath directory delimiter #and replace in case of using Linux path print("caminhoArquivo1=" + caminhoArquivo) caminhoArquivo.replace("/","\\") print("caminhoArquivo2=" + caminhoArquivo) command = '' if not (os.path.isfile(diretorioDestino+os.path.dirname(caminhoSalvar) + "\\" + nomeArquivo + '.zr')): command = ['robocopy', os.path.dirname(caminhoArquivo), diretorioDestino+os.path.dirname(caminhoSalvar), nomeArquivo] #command = ['robocopy', os.path.dirname(caminhoArquivo), diretorioDestino, nomeArquivo] print("Caminho de onde foi copiado = " + os.path.dirname(caminhoArquivo)+"\\"+nomeArquivo) print("CaminhoNovoArquivo = " + diretorioDestino + os.path.dirname(caminhoSalvar)) if command is not '': self.p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out = self.p.stdout.readline(500) if out is not '': self.dlg.textEditDownloadProgress.setText(out) sys.stdout.flush() PyQt4.QtGui.QApplication.processEvents() #update UI while self.p.poll() is None: out = self.p.stdout.readline(500) match = re.search('\\r.+\\r',out) if out is not '' and match is not None: self.dlg.textEditDownloadProgress.setText(match.group(0).split('\r')[1]) sys.stdout.flush() PyQt4.QtGui.QApplication.processEvents() #arq = open(diretorioDestino + '/' + nomeArquivo + '.zr', "w") print('Caminho ZR 1= ' + diretorioDestino+os.path.dirname(caminhoSalvar)) if not os.path.exists(diretorioDestino+os.path.dirname(caminhoSalvar)): os.makedirs(diretorioDestino+os.path.dirname(caminhoSalvar)) arq = open(diretorioDestino+os.path.dirname(caminhoSalvar) + "\\" + nomeArquivo + '.zr', "w") arq.close() elif "linux" in _platform: #for generic use, test fullpath directory delimiter #and replace in case of using Windows UNC caminhoArquivo.replace("\\","/") command = '' command1 = '' if not (os.path.isfile(diretorioDestino+os.path.dirname(caminhoSalvar) + '/' + nomeArquivo + '.zr', "w")): #testing if file path is samba relative #TODO - Define other methods if ("smb" in caminhoArquivo): #defining command (depends on smbclient tools installed) command = ['/usr/bin/smbget', '--guest', '--nonprompt', caminhoArquivo, '-o', '%s/%s' % (diretorioDestino+os.path.dirname(caminhoSalvar), nomeArquivo)] if command is not '': self.p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) #update UI while self.p.poll() is None: out = self.p.stdout.readline(500) match = re.search('\\r.+\\r',out) if out is not '' and match is not None: self.dlg.textEditDownloadProgress.setText(match.group(0).split('\r')[1]) sys.stdout.flush() PyQt4.QtGui.QApplication.processEvents() arq = open(diretorioDestino+os.path.dirname(caminhoSalvar) + '/' + nomeArquivo + '.zr', "w") arq.close() else: #levantar exceção de plataforma não identificada pass return def moveArquivo(self, caminhoArquivo, nomeArquivio): #print "Nome Original111 => " + str(caminhoArquivo) #print "Nome Original111 => " + str(nomeArquivio) diretorio = self.dlg.lineEdit.text() diretorioNovoArquivo = os.path.dirname(os.path.realpath(caminhoArquivo)) if not os.path.exists(diretorio + diretorioNovoArquivo): os.makedirs(diretorio + diretorioNovoArquivo) shutil.copy2(caminhoArquivo, diretorio + caminhoArquivo) #print "Pasta destino" + self.dlg.lineEdit.text return def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget elf.modelt.headerData(i, Qt.Horizontal, 0)param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/UploadImages/upload.png' self.add_action( icon_path, text=self.tr(u'Upload Images'), callback=self.run, parent=self.iface.mainWindow()) icon_path = ':/plugins/UploadImages/upload.png' self.add_action( icon_path, text=self.tr(u'Upload Images11111'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&Upload Images'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def populateTable(self): actlayer = qgis.utils.iface.activeLayer() self.features = actlayer.selectedFeatures() fidlist = [] if len(self.features) > 0: for f in self.features: fidlist.append(f[self.keycolumn]) selection=[] strsel=self.keycolumn + " IN (" for fid in fidlist: selection.append(fid) strsel=strsel+ "'" + str(fid) + "'," strsel=strsel[:-1] + ")" actlayer.setSubsetString(strsel) cache = QgsVectorLayerCache(actlayer, 50000) self.modelt = QgsAttributeTableModel(cache) self.modelt.loadLayer() table = self.dlg.tableView table.setModel(self.modelt) self.dlg.show() self.dlg.exec_() else: self.iface.messageBar().pushMessage("Error", QCoreApplication.translate("sipamsar","At least one feature need to be selected."), level=QgsMessageBar.WARNING) QgsMessageLog.logMessage("At least one feature need to be selected.", level=QgsMessageLog.WARNING) def populateFields(self): actlayer = qgis.utils.iface.activeLayer() cache = QgsVectorLayerCache(actlayer, 50000) self.modelc = QgsAttributeTableModel(cache) self.modelc.loadLayer() index = self.modelc.index(0,0) campos = [] for i in range(0,self.modelc.columnCount(index)): campos.append(self.modelc.headerData(i, Qt.Horizontal, Qt.DisplayRole)) self.dlg.comboBoxCampos.addItems(campos) def run(self): """Run method that performs all the real work""" #self.dlg.comboBox.clear() actlayer = qgis.utils.iface.activeLayer() if actlayer is None: self.iface.messageBar().pushMessage("Error", QCoreApplication.translate("sipamsar","No loaded layer available. Please, choose one layer and select the features to download/upload."), level=QgsMessageBar.WARNING) QgsMessageLog.logMessage("No loaded layer available. Please, choose one layer and select the features to download/upload.", level=QgsMessageLog.WARNING) return dsu = QgsDataSourceURI( actlayer.dataProvider().dataSourceUri() ) self.keycolumn = dsu.keyColumn() self.populateFields() self.populateTable()
class TestQgsAttributeTableModel(unittest.TestCase): @classmethod def setUpClass(cls): QgsGui.editorWidgetRegistry().initEditors() def setUp(self): self.layer = self.createLayer() self.cache = QgsVectorLayerCache(self.layer, 100) self.am = QgsAttributeTableModel(self.cache) self.am.loadLayer() def tearDown(self): del self.am del self.cache del self.layer def createLayer(self): layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer", "addfeat", "memory") pr = layer.dataProvider() features = list() for i in range(10): f = QgsFeature() f.setAttributes(["test", i]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100 * i, 2 ^ i))) features.append(f) self.assertTrue(pr.addFeatures(features)) return layer def testLoad(self): self.assertEqual(self.am.rowCount(), 10) self.assertEqual(self.am.columnCount(), 2) def testRemove(self): self.layer.startEditing() self.layer.deleteFeature(5) self.assertEqual(self.am.rowCount(), 9) self.layer.selectByIds([1, 3, 6, 7]) self.layer.deleteSelectedFeatures() self.assertEqual(self.am.rowCount(), 5) def testAdd(self): self.layer.startEditing() f = QgsFeature() f.setAttributes(["test", 8]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(100, 200))) self.layer.addFeature(f) self.assertEqual(self.am.rowCount(), 11) def testRemoveColumns(self): self.assertTrue(self.layer.startEditing()) self.assertTrue(self.layer.deleteAttribute(1)) self.assertEqual(self.am.columnCount(), 1) def testEdit(self): fid = 2 field_idx = 1 new_value = 333 # get the same feature from model and layer feature = self.layer.getFeature(fid) model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that feature from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) # change attribute value for a feature and commit self.layer.startEditing() self.layer.changeAttributeValue(fid, field_idx, new_value) self.layer.commitChanges() # check the feature in layer is good feature = self.layer.getFeature(fid) self.assertEqual(feature.attribute(field_idx), new_value) # get the same feature from model and layer model_index = self.am.idToIndex(fid) feature_model = self.am.feature(model_index) # check that index from layer and model are sync self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx)) def testStyle(self): style_threshold = 2 color = QColor(133, 133, 133) style = QgsConditionalStyle() style.setRule(f'"fldint" <= {style_threshold}') style.setTextColor(color) self.layer.conditionalStyles().setRowStyles([style]) for f in self.layer.getFeatures(): model_index = self.am.idToIndex(f.id()) text_color = self.am.data(model_index, Qt.TextColorRole) if f['fldint'] <= style_threshold: self.assertEqual(text_color, color) else: self.assertIsNone(text_color) self.assertTrue(self.layer.startEditing()) feature1 = self.layer.getFeature(2) feature1['fldint'] = style_threshold + 1 feature2 = self.layer.getFeature(8) feature2['fldint'] = style_threshold self.assertTrue(self.layer.updateFeature(feature1)) self.assertTrue(self.layer.updateFeature(feature2)) self.assertTrue(self.layer.commitChanges()) for f in self.layer.getFeatures(): model_index = self.am.idToIndex(f.id()) text_color = self.am.data(model_index, Qt.TextColorRole) if f['fldint'] <= style_threshold: self.assertEqual(color, text_color, f'Feature {f.id()} should have color') else: self.assertIsNone(text_color, f'Feature {f.id()} should have no color') self.layer.conditionalStyles().setRowStyles([])