def detectTripleStoreConfiguration(self): progress = QProgressDialog("Detecting configuration for triple store "+self.tripleStoreEdit.text()+"...", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask=DetectTripleStoreTask("Detecting configuration for triple store "+self.tripleStoreEdit.text()+"...",self.triplestoreconf,self.tripleStoreEdit.text(),self.tripleStoreNameEdit.text(),False,True,self.prefixes,self.prefixstore,self.tripleStoreChooser,self.comboBox,progress) QgsApplication.taskManager().addTask(self.qtask)
def loadURI(self): if self.graphURIEdit.text()!="": progress = QProgressDialog("Loading Graph from "+self.graphURIEdit.text(), "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=LoadGraphTask("Loading Graph: "+self.graphURIEdit.text(), self.graphURIEdit.text(),self,self.dlg,self.maindlg,self.triplestoreconf[0]["geoconceptquery"],self.triplestoreconf,progress) QgsApplication.taskManager().addTask(self.qtask)
def testTripleStoreConnection(self,calledfromotherfunction=False,showMessageBox=True,query="SELECT ?a ?b ?c WHERE { ?a ?b ?c .} LIMIT 1"): progress = QProgressDialog("Checking connection to triple store "+self.tripleStoreEdit.text()+"...", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask=DetectTripleStoreTask("Checking connection to triple store "+self.tripleStoreEdit.text()+"...",self.triplestoreconf,self.tripleStoreEdit.text(),self.tripleStoreNameEdit.text(),True,False,self.prefixes,self.prefixstore,self.tripleStoreChooser,self.comboBox,progress) QgsApplication.taskManager().addTask(self.qtask)
def create_unicorn_layer(self): endpointIndex = self.dlg.comboBox.currentIndex() # SPARQL query #print(self.loadedfromfile) # query query = self.dlg.inp_sparql2.toPlainText() if self.loadedfromfile: curindex = self.dlg.proxyModel.mapToSource( self.dlg.geoClassList.selectionModel().currentIndex()) if curindex != None and self.dlg.geoClassListModel.itemFromIndex( curindex) != None: concept = self.dlg.geoClassListModel.itemFromIndex( curindex).data(1) else: concept = "http://www.opengis.net/ont/geosparql#Feature" geojson = self.getGeoJSONFromGeoConcept(self.currentgraph, concept) vlayer = QgsVectorLayer( json.dumps(geojson, sort_keys=True, indent=4), "unicorn_" + self.dlg.inp_label.text(), "ogr") print(vlayer.isValid()) QgsProject.instance().addMapLayer(vlayer) canvas = iface.mapCanvas() canvas.setExtent(vlayer.extent()) iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success) #iface.messageBar().pushMessage("Error", "An error occured", level=Qgis.Critical) #self.dlg.close() return else: endpoint_url = self.triplestoreconf[endpointIndex]["endpoint"] missingmandvars = [] for mandvar in self.triplestoreconf[endpointIndex][ "mandatoryvariables"]: if mandvar not in query: missingmandvars.append("?" + mandvar) if missingmandvars != [] and not self.dlg.allownongeo.isChecked(): msgBox = QMessageBox() msgBox.setWindowTitle("Mandatory variables missing!") msgBox.setText( "The SPARQL query is missing the following mandatory variables: " + str(missingmandvars)) msgBox.exec() progress = QProgressDialog( "Querying layer from " + endpoint_url + "...", "Abort", 0, 0, self.dlg) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.show() self.qtask = QueryLayerTask( "Querying QGIS Layer from " + endpoint_url, endpoint_url, "".join(self.prefixes[endpointIndex]) + query, self.triplestoreconf[endpointIndex], self.dlg.allownongeo.isChecked(), self.dlg.inp_label.text(), progress) QgsApplication.taskManager().addTask(self.qtask)
def loadFile(self): dialog = QFileDialog(self.dlg) dialog.setFileMode(QFileDialog.AnyFile) self.justloadingfromfile=True if dialog.exec_(): fileNames = dialog.selectedFiles() filepath=fileNames[0].split(".") progress = QProgressDialog("Loading Graph: "+fileNames[0], "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=LoadGraphTask("Loading Graph: "+fileNames[0], fileNames[0],self,self.dlg,self.maindlg,self.triplestoreconf[0]["geoconceptquery"],self.triplestoreconf,progress) QgsApplication.taskManager().addTask(self.qtask)
def getAttributeStatistics(self,concept="wd:Q3914",endpoint_url="https://query.wikidata.org/sparql",labellang="en",inarea="wd:Q183"): if self.conceptSearchEdit.text()=="": return concept="<"+self.conceptSearchEdit.text()+">" progress = QProgressDialog("Executing enrichment search query....", "Abort", 0, 0, self) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask=WhatToEnrichQueryTask("Get Property Enrichment Candidates ("+self.conceptSearchEdit.text()+")", endpoint_url, self.triplestoreconf[self.tripleStoreEdit.currentIndex()+1]["whattoenrichquery"].replace("%%concept%%",concept).replace("%%area%%","?area"), self.conceptSearchEdit.text(), self.prefixes[self.tripleStoreEdit.currentIndex()], self.searchResult,progress) QgsApplication.taskManager().addTask(self.qtask)
def execute(func, message = None, useThread = False): global _dialog cursor = QApplication.overrideCursor() waitCursor = (cursor is not None and cursor.shape() == Qt.WaitCursor) dialogCreated = False try: QCoreApplication.processEvents() if not waitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if message is not None and useThread: t = Thread(func) loop = QEventLoop() t.finished.connect(loop.exit, Qt.QueuedConnection) if _dialog is None: dialogCreated = True _dialog = QProgressDialog(message, "Mapstory", 0, 0, config.iface.mainWindow()) _dialog.setWindowTitle("Mapstory") _dialog.setWindowModality(Qt.WindowModal); _dialog.setMinimumDuration(1000) _dialog.setMaximum(100) _dialog.setValue(0) _dialog.setMaximum(0) _dialog.setCancelButton(None) else: oldText = _dialog.labelText() _dialog.setLabelText(message) QApplication.processEvents() t.start() loop.exec_(flags = QEventLoop.ExcludeUserInputEvents) if t.exception is not None: raise t.exception return t.returnValue else: return func() finally: if message is not None and useThread: if dialogCreated: _dialog.reset() _dialog = None else: _dialog.setLabelText(oldText) if not waitCursor: QApplication.restoreOverrideCursor() QCoreApplication.processEvents()
def enrichLayerProcess(self): layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex() self.enrichLayer = layers[selectedLayerIndex].layer().clone() attlist = {} itemlist = [] propertylist = [] excludelist = [] resultmap = {} self.dlg.enrichTableResult.clear() self.dlg.enrichTableResult.setRowCount(0) self.dlg.enrichTableResult.setColumnCount( self.dlg.enrichTable.rowCount()) fieldnames = [] for row in range(self.dlg.enrichTable.rowCount()): fieldnames.append(self.dlg.enrichTable.item(row, 0).text()) self.dlg.enrichTableResult.setHorizontalHeaderLabels(fieldnames) self.enrichLayer.startEditing() for row in range(self.dlg.enrichTable.rowCount()): idfield = self.dlg.enrichTable.cellWidget(row, 5).currentText() idprop = self.dlg.enrichTable.item(row, 6).text() if idprop == None or idprop == "": msgBox = QMessageBox() msgBox.setText( "ID Property has not been specified for column " + str(self.dlg.enrichTable.item(row, 0).text())) msgBox.exec() return item = self.dlg.enrichTable.item(row, 0).text() propertyy = self.dlg.enrichTable.item(row, 1) triplestoreurl = "" if self.dlg.enrichTable.item(row, 2) != None: triplestoreurl = self.dlg.enrichTable.item(row, 2).text() print(self.dlg.enrichTable.item(row, 2).text()) strategy = self.dlg.enrichTable.cellWidget(row, 3).currentText() content = "" if self.dlg.enrichTable.cellWidget(row, 4) != None: content = self.dlg.enrichTable.cellWidget(row, 4).currentText() if item != idfield: propertylist.append(self.dlg.enrichTable.item(row, 1)) if strategy == "Exclude": excludelist.append(row) if strategy != "No Enrichment" and propertyy != None: progress = QProgressDialog( "Enriching column " + self.dlg.enrichTable.item(row, 0).text(), "Abort", 0, 0, self.dlg) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) self.qtask = EnrichmentQueryTask( "Enriching column: " + self.dlg.enrichTable.item(row, 0).text(), triplestoreurl, self.enrichLayer, strategy, self.dlg.enrichTable.item(row, 8).text(), row, len(self.enrichLayer.fields()), self.dlg.enrichTable.item(row, 0).text(), self.dlg.enrichTable, self.dlg.enrichTableResult, idfield, idprop, self.dlg.enrichTable.item(row, 1), content, progress) QgsApplication.taskManager().addTask(self.qtask) else: rowww = 0 for f in self.enrichLayer.getFeatures(): if rowww >= self.dlg.enrichTableResult.rowCount(): self.dlg.enrichTableResult.insertRow(rowww) #if item in f: newitem = QTableWidgetItem(str(f[item])) self.dlg.enrichTableResult.setItem(rowww, row, newitem) #if ";" in str(newitem): # newitem.setBackground(QColor.red) print(str(newitem)) rowww += 1 self.enrichLayer.commitChanges() row += 1 iface.vectorLayerTools().stopEditing(self.enrichLayer) self.enrichLayer.dataProvider().deleteAttributes(excludelist) self.enrichLayer.updateFields() self.dlg.enrichTable.hide() self.dlg.enrichTableResult.show() self.dlg.startEnrichment.setText("Enrichment Configuration") self.dlg.startEnrichment.clicked.disconnect() self.dlg.startEnrichment.clicked.connect(self.dlg.showConfigTable) self.dlg.addEnrichedLayerRowButton.setEnabled(False) return self.enrichLayer
def action_import(plugin, pgservice=None): """ Is executed when the user clicks the importAction tool """ global import_dialog # avoid garbage collection if not configure_from_modelbaker(plugin.iface): return if pgservice: config.PGSERVICE = pgservice default_folder = QgsSettings().value("qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getOpenFileName( None, plugin.tr("Import file"), default_folder, plugin.tr("Interlis transfer files (*.xtf)")) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Validating the input file progress_dialog.setLabelText("Validating the input file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The input file is not a valid XTF file. Open the logs for more details on the error.", log_path, ) return # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(33) # Export from ili2pg model to file progress_dialog.setLabelText("Importing XTF data...") QApplication.processEvents() log_path = make_log_path(None, "import") try: import_xtf_data( config.ABWASSER_SCHEMA, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not import data", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(66) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting to QGEP...") QApplication.processEvents() import_dialog = GuiImport(plugin.iface.mainWindow()) progress_dialog.setValue(100) qgep_import(precommit_callback=import_dialog.init_with_session, )
def action_do_export(): default_folder = QgsSettings().value( "qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getSaveFileName( None, plugin.tr("Export to file"), os.path.join(default_folder, "qgep-export.xtf"), plugin.tr("Interlis transfer files (*.xtf)"), ) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(25) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting from QGEP...") QApplication.processEvents() qgep_export(selection=export_dialog.selected_ids) progress_dialog.setValue(50) # Export from ili2pg model to file progress_dialog.setLabelText("Saving XTF file...") QApplication.processEvents() log_path = make_log_path(None, "export") try: export_xtf_data( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL_NAME, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not export the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(75) progress_dialog.setLabelText("Validating the output file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The created file is not a valid XTF file.", log_path, ) return progress_dialog.setValue(100) show_success( "Sucess", f"Data successfully exported to {file_name}", os.path.dirname(log_path), )
class AttributesTable(QWidget): def __init__(self, iface): QWidget.__init__(self) self.setWindowTitle(self.tr('Search results')) self.resize(480,320) self.setMinimumSize(320,240) self.center() # Results export button self.btn_saveTab = QAction(QIcon(':/plugins/qgeric/resources/icon_save.png'), self.tr('Save this tab\'s results'), self) self.btn_saveTab.triggered.connect(lambda : self.saveAttributes(True)) self.btn_saveAllTabs = QAction(QIcon(':/plugins/qgeric/resources/icon_saveAll.png'), self.tr('Save all results'), self) self.btn_saveAllTabs.triggered.connect(lambda : self.saveAttributes(False)) self.btn_export = QAction(QIcon(':/plugins/qgeric/resources/icon_export.png'), self.tr('Export the selection as a memory layer'), self) self.btn_export.triggered.connect(self.exportLayer) self.btn_zoom = QAction(QIcon(':/plugins/qgeric/resources/icon_Zoom.png'), self.tr('Zoom to selected attributes'), self) self.btn_zoom.triggered.connect(self.zoomToFeature) self.btn_selectGeom = QAction(QIcon(':/plugins/qgeric/resources/icon_HlG.png'), self.tr('Highlight feature\'s geometry'), self) self.btn_selectGeom.triggered.connect(self.selectGeomChanged) self.btn_rename = QAction(QIcon(':/plugins/qgeric/resources/icon_Settings.png'), self.tr('Settings'), self) self.btn_rename.triggered.connect(self.renameWindow) self.tabWidget = QTabWidget() # Tab container self.tabWidget.setTabsClosable(True) self.tabWidget.currentChanged.connect(self.highlight_features) self.tabWidget.tabCloseRequested.connect(self.closeTab) self.loadingWindow = QProgressDialog() self.loadingWindow.setWindowTitle(self.tr('Loading...')) self.loadingWindow.setRange(0,100) self.loadingWindow.setAutoClose(False) self.loadingWindow.setCancelButton(None) self.canvas = iface.mapCanvas() self.canvas.extentsChanged.connect(self.highlight_features) self.highlight = [] self.highlight_rows = [] toolbar = QToolBar() toolbar.addAction(self.btn_saveTab) toolbar.addAction(self.btn_saveAllTabs) toolbar.addAction(self.btn_export) toolbar.addSeparator() toolbar.addAction(self.btn_zoom) toolbar.addSeparator() toolbar.addAction(self.btn_selectGeom) toolbar.addAction(self.btn_rename) vbox = QVBoxLayout() vbox.setContentsMargins(0,0,0,0) vbox.addWidget(toolbar) vbox.addWidget(self.tabWidget) self.setLayout(vbox) self.mb = iface.messageBar() self.selectGeom = False # False for point, True for geometry def renameWindow(self): title, ok = QInputDialog.getText(self, self.tr('Rename window'), self.tr('Enter a new title:')) if ok: self.setWindowTitle(title) def closeTab(self, index): self.tabWidget.widget(index).deleteLater() self.tabWidget.removeTab(index) def selectGeomChanged(self): if self.selectGeom: self.selectGeom = False self.btn_selectGeom.setText(self.tr('Highlight feature\'s geometry')) self.btn_selectGeom.setIcon(QIcon(':/plugins/qgeric/resources/icon_HlG.png')) else: self.selectGeom = True self.btn_selectGeom.setText(self.tr('Highlight feature\'s centroid')) self.btn_selectGeom.setIcon(QIcon(':/plugins/qgeric/resources/icon_HlC.png')) self.highlight_features() def exportLayer(self): if self.tabWidget.count() != 0: index = self.tabWidget.currentIndex() table = self.tabWidget.widget(index).findChildren(QTableWidget)[0] items = table.selectedItems() if len(items) > 0: type = '' if items[0].feature.geometry().type() == QgsWkbTypes.PointGeometry: type = 'Point' elif items[0].feature.geometry().type() == QgsWkbTypes.LineGeometry: type = 'LineString' else: type = 'Polygon' features = [] for item in items: if item.feature not in features: features.append(item.feature) name = '' ok = True while not name.strip() and ok == True: name, ok = QInputDialog.getText(self, self.tr('Layer name'), self.tr('Give a name to the layer:')) if ok: layer = QgsVectorLayer(type+"?crs="+table.crs.authid(),name,"memory") layer.startEditing() layer.dataProvider().addAttributes(features[0].fields().toList()) layer.dataProvider().addFeatures(features) layer.commitChanges() QgsProject.instance().addMapLayer(layer) else: self.mb.pushWarning(self.tr('Warning'), self.tr('There is no selected feature !')) def highlight_features(self): for item in self.highlight: self.canvas.scene().removeItem(item) del self.highlight[:] del self.highlight_rows[:] index = self.tabWidget.currentIndex() tab = self.tabWidget.widget(index) if self.tabWidget.count() != 0: table = self.tabWidget.widget(index).findChildren(QTableWidget)[0] nb = 0 area = 0 length = 0 items = table.selectedItems() for item in items: if item.row() not in self.highlight_rows: if self.selectGeom: highlight = QgsHighlight(self.canvas, item.feature.geometry(), self.tabWidget.widget(index).layer) else: highlight = QgsHighlight(self.canvas, item.feature.geometry().centroid(), self.tabWidget.widget(index).layer) highlight.setColor(QColor(255,0,0)) self.highlight.append(highlight) self.highlight_rows.append(item.row()) g = QgsGeometry(item.feature.geometry()) g.transform(QgsCoordinateTransform(tab.layer.crs(), QgsCoordinateReferenceSystem(2154), QgsProject.instance())) # geometry reprojection to get meters nb += 1 area += g.area() length += g.length() if tab.layer.geometryType()==QgsWkbTypes.PolygonGeometry: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb)+' '+self.tr('Area')+': '+"%.2f"%area+' m'+u'²') elif tab.layer.geometryType()==QgsWkbTypes.LineGeometry: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb)+' '+self.tr('Length')+': '+"%.2f"%length+' m') else: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb)) def tr(self, message): return QCoreApplication.translate('Qgeric', message) def zoomToFeature(self): index = self.tabWidget.currentIndex() table = self.tabWidget.widget(index).findChildren(QTableWidget)[0] items = table.selectedItems() feat_id = [] for item in items: feat_id.append(item.feature.id()) if len(feat_id) >= 1: if len(feat_id) == 1: self.canvas.setExtent(items[0].feature.geometry().buffer(5, 0).boundingBox()) # in case of a single point, it will still zoom to it else: self.canvas.zoomToFeatureIds(self.tabWidget.widget(self.tabWidget.currentIndex()).layer, feat_id) self.canvas.refresh() # Add a new tab def addLayer(self, layer, headers, types, features): tab = QWidget() tab.layer = layer p1_vertical = QVBoxLayout(tab) p1_vertical.setContentsMargins(0,0,0,0) table = QTableWidget() table.itemSelectionChanged.connect(self.highlight_features) table.title = layer.name() table.crs = layer.crs() table.setColumnCount(len(headers)) if len(features) > 0: table.setRowCount(len(features)) nbrow = len(features) self.loadingWindow.show() self.loadingWindow.setLabelText(table.title) self.loadingWindow.activateWindow() self.loadingWindow.showNormal() # Table population m = 0 for feature in features: n = 0 for cell in feature.attributes(): item = QTableWidgetItem() item.setData(Qt.DisplayRole, cell) item.setFlags(item.flags() ^ Qt.ItemIsEditable) item.feature = feature table.setItem(m, n, item) n += 1 m += 1 self.loadingWindow.setValue(int((float(m)/nbrow)*100)) QApplication.processEvents() else: table.setRowCount(0) table.setHorizontalHeaderLabels(headers) table.horizontalHeader().setSectionsMovable(True) table.types = types table.filter_op = [] table.filters = [] for i in range(0, len(headers)): table.filters.append('') table.filter_op.append(0) header = table.horizontalHeader() header.setContextMenuPolicy(Qt.CustomContextMenu) header.customContextMenuRequested.connect(partial(self.filterMenu, table)) table.setSortingEnabled(True) p1_vertical.addWidget(table) # Status bar to display informations (ie: area) tab.sb = QStatusBar() p1_vertical.addWidget(tab.sb) title = table.title # We reduce the title's length to 20 characters if len(title)>20: title = title[:20]+'...' # We add the number of elements to the tab's title. title += ' ('+str(len(features))+')' self.tabWidget.addTab(tab, title) # Add the tab to the conatiner self.tabWidget.setTabToolTip(self.tabWidget.indexOf(tab), table.title) # Display a tooltip with the layer's full name def filterMenu(self, table, pos): index = table.columnAt(pos.x()) menu = QMenu() filter_operation = QComboBox() if table.types[index] in [10]: filter_operation.addItems([self.tr('Contains'),self.tr('Equals')]) else: filter_operation.addItems(['=','>','<']) filter_operation.setCurrentIndex(table.filter_op[index]) action_filter_operation = QWidgetAction(self) action_filter_operation.setDefaultWidget(filter_operation) if table.types[index] in [14]: if not isinstance(table.filters[index], QDate): filter_value = QDateEdit() else: filter_value = QDateEdit(table.filters[index]) elif table.types[index] in [15]: if not isinstance(table.filters[index], QTime): filter_value = QTimeEdit() else: filter_value = QTimeEdit(table.filters[index]) elif table.types[index] in [16]: if not isinstance(table.filters[index], QDateTime): filter_value = QDateTimeEdit() else: filter_value = QDateTimeEdit(table.filters[index]) else: filter_value = QLineEdit(table.filters[index]) action_filter_value = QWidgetAction(self) action_filter_value.setDefaultWidget(filter_value) menu.addAction(action_filter_operation) menu.addAction(action_filter_value) action_filter_apply = QAction(self.tr('Apply'), self) action_filter_apply.triggered.connect(partial(self.applyFilter, table, index, filter_value, filter_operation)) action_filter_cancel = QAction(self.tr('Cancel'), self) action_filter_cancel.triggered.connect(partial(self.applyFilter, table, index, None, filter_operation)) menu.addAction(action_filter_apply) menu.addAction(action_filter_cancel) menu.exec_(QtGui.QCursor.pos()) def applyFilter(self, table, index, filter_value, filter_operation): if filter_value == None: table.filters[index] = None else: if isinstance(filter_value, QDateEdit): table.filters[index] = filter_value.date() elif isinstance(filter_value, QTimeEdit): table.filters[index] = filter_value.time() elif isinstance(filter_value, QDateTimeEdit): table.filters[index] = filter_value.dateTime() else: table.filters[index] = filter_value.text() table.filter_op[index] = filter_operation.currentIndex() nb_elts = 0 for i in range(0, table.rowCount()): table.setRowHidden(i, False) nb_elts += 1 hidden_rows = [] for nb_col in range(0, table.columnCount()): filtered = False header = table.horizontalHeaderItem(nb_col).text() valid = False if table.filters[nb_col] is not None: if type(table.filters[nb_col]) in [QDate, QTime, QDateTime]: valid = True else: if table.filters[nb_col].strip(): valid = True if valid: filtered = True items = None if table.types[nb_col] in [10]:# If it's a string filter_type = None if table.filter_op[nb_col] == 0: # Contain filter_type = Qt.MatchContains if table.filter_op[nb_col] == 1: # Equal filter_type = Qt.MatchFixedString items = table.findItems(table.filters[nb_col], filter_type) elif table.types[nb_col] in [14, 15, 16]: # If it's a date/time items = [] for nb_row in range(0, table.rowCount()): item = table.item(nb_row, nb_col) if table.filter_op[nb_col] == 0: # = if item.data(QTableWidgetItem.Type) == table.filters[nb_col]: items.append(item) if table.filter_op[nb_col] == 1: # > if item.data(QTableWidgetItem.Type) > table.filters[nb_col]: items.append(item) if table.filter_op[nb_col] == 2: # < if item.data(QTableWidgetItem.Type) < table.filters[nb_col]: items.append(item) else: # If it's a number items = [] for nb_row in range(0, table.rowCount()): item = table.item(nb_row, nb_col) if item.text().strip(): if table.filter_op[nb_col] == 0: # = if float(item.text()) == float(table.filters[nb_col]): items.append(item) if table.filter_op[nb_col] == 1: # > if float(item.text()) > float(table.filters[nb_col]): items.append(item) if table.filter_op[nb_col] == 2: # < if float(item.text()) < float(table.filters[nb_col]): items.append(item) rows = [] for item in items: if item.column() == nb_col: rows.append(item.row()) for i in range(0, table.rowCount()): if i not in rows: if i not in hidden_rows: nb_elts -= 1 table.setRowHidden(i, True) hidden_rows.append(i) if filtered: if header[len(header)-1] != '*': table.setHorizontalHeaderItem(nb_col, QTableWidgetItem(header+'*')) else: if header[len(header)-1] == '*': header = header[:-1] table.setHorizontalHeaderItem(nb_col, QTableWidgetItem(header)) title = self.tabWidget.tabText(self.tabWidget.currentIndex()) for i in reversed(range(len(title))): if title[i] == ' ': break title = title[:-1] title += '('+str(nb_elts)+')' self.tabWidget.setTabText(self.tabWidget.currentIndex(), title) # Save tables in OpenDocument format # Use odswriter library def saveAttributes(self, active): file = QFileDialog.getSaveFileName(self, self.tr('Save in...'),'', self.tr('OpenDocument Spreadsheet (*.ods)')) if file[0]: try: with ods.writer(open(file[0],"wb")) as odsfile: tabs = None if active: tabs = self.tabWidget.currentWidget().findChildren(QTableWidget) else: tabs = self.tabWidget.findChildren(QTableWidget) for table in reversed(tabs): sheet = odsfile.new_sheet(table.title[:20]+'...') # For each tab in the container, a new sheet is created sheet.writerow([table.title]) # As the tab's title's lenght is limited, the full name of the layer is written in the first row nb_row = table.rowCount() nb_col = table.columnCount() # Fetching and writing of the table's header header = [] for i in range(0,nb_col): header.append(table.horizontalHeaderItem(i).text()) sheet.writerow(header) # Fetching and writing of the table's items for i in range(0,nb_row): row = [] for j in range(0,nb_col): row.append(table.item(i,j).text()) if not table.isRowHidden(i): sheet.writerow(row) return True except IOError: QMessageBox.critical(self, self.tr('Error'), self.tr('The file can\'t be written.')+'\n'+self.tr('Maybe you don\'t have the rights or are trying to overwrite an opened file.')) return False def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2) def clear(self): self.tabWidget.clear() for table in self.tabWidget.findChildren(QTableWidget): table.setParent(None) def closeEvent(self, e): result = QMessageBox.question(self, self.tr("Saving ?"), self.tr("Would you like to save results before exit ?"), buttons = QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if result == QMessageBox.Yes: if self.saveAttributes(False): self.clear() e.accept() else: e.ignore() elif result == QMessageBox.No: self.clear() e.accept() else: e.ignore()