class QVDistrictesBarris(QObject): __distBarrisCSV = r'Dades\DIST_BARRIS.csv' __zones = r'Dades\Zones.gpkg' def __init__(self): super().__init__() self.labels = [] self.registre = {} # Model self.model = QStandardItemModel() self.llegirZonesGPKG() #self.llegirDistrictesBarrisCSV() # View self.view = QTreeView() self.view.setContextMenuPolicy(Qt.ActionsContextMenu) self.actExpand = QAction("Expandeix/Contreu Tot", self) self.actExpand.setStatusTip("Expand") self.actExpand.triggered.connect(self.expand_all) self.view.addAction(self.actExpand) self.view.setModel(self.model) self.iniView() def expand_all(self): """Expandir o contraer todo el arbol, dependiendo de si detecta que esta extendido o contraido """ if self.view.isExpanded(self.model.index(0, 0, QModelIndex())): self.view.collapseAll() else: self.view.expandAll() def iniView(self): self.view.setHeaderHidden(True) for i in range(self.model.columnCount()): if i == 0: self.view.setColumnHidden(i, False) self.view.resizeColumnToContents(i) self.view.resizeColumnToContents(i) else: self.view.setColumnHidden(i, True) self.view.setEditTriggers(QTreeView.NoEditTriggers) self.expand_all() def llegirZonesGPKG(self): try: QvFuncions.setReadOnlyFile(self.__zones) pathDistrictes = self.__zones + '|layername=districtes' layerDistrictes = QgsVectorLayer(pathDistrictes, 'ogr') pathBarris = self.__zones + '|layername=barris' layerBarris = QgsVectorLayer(pathBarris, 'ogr') rowsDistrictes = layerDistrictes.getFeatures() llistaDistrictes = [] for rowD in rowsDistrictes: #print(rowD.attributes()) #zona = "" num_districte = rowD.attributes()[1] nom_districte = rowD.attributes()[2] num_barri = "" nom_barri = "" geometria = rowD.geometry().boundingBox() x_min = str(geometria.xMinimum()) y_min = str(geometria.yMinimum()) x_max = str(geometria.xMaximum()) y_max = str(geometria.yMaximum()) item = [ num_districte, nom_districte, num_barri, nom_barri, x_min, y_min, x_max, y_max ] llistaDistrictes.append(item) def ordenaPerNumDistricte(elem): return elem[0] llistaDistrictes.sort(key=ordenaPerNumDistricte) #print(llistaDistrictes) rowsBarris = layerBarris.getFeatures() llistaBarris = [] for rowB in rowsBarris: #print(rowB.attributes()) #zona = "" num_districte = rowB.attributes()[3] nom_districte = llistaDistrictes[int(num_districte) - 1][1] num_barri = rowB.attributes()[1] nom_barri = rowB.attributes()[2] geometria = rowB.geometry().boundingBox() x_min = str(geometria.xMinimum()) y_min = str(geometria.yMinimum()) x_max = str(geometria.xMaximum()) y_max = str(geometria.yMaximum()) item = [ num_districte, nom_districte, num_barri, nom_barri, x_min, y_min, x_max, y_max ] llistaBarris.append(item) def ordenaPerNumBarri(elem): return elem[2] llistaBarris.sort(key=ordenaPerNumBarri) #print(llistaBarris) self.labels = [ "ZONA", "DISTRICTE", "NOM_DISTRICTE", "BARRI", "NOM_BARRI", "X_MIN", "Y_MIN", "X_MAX", "Y_MAX" ] root = self.model.invisibleRootItem() self.model.setColumnCount(len(self.labels)) self.model.setHorizontalHeaderLabels(self.labels) #Afegir Barcelona com a arrel de l'arbre bcn_dades = [ "00", "Barcelona", "00", "Barcelona", "419710.0553820258", "4573818.80776309", "436533.35", "4591775.02" ] bcn = [QStandardItem("Barcelona")] for item in bcn_dades: bcn.append(QStandardItem(item)) root.appendRow(bcn) ultimaDistr = -1 itDist = 0 for b in llistaBarris: if ultimaDistr != int(b[0]): #Afegir següent districte dist = [QStandardItem(llistaDistrictes[itDist][1])] for i in range(0, len(llistaDistrictes[itDist])): dist.append(QStandardItem(llistaDistrictes[itDist][i])) bcn[0].appendRow(dist) itDist = itDist + 1 #Afegir següent Barri barri = [QStandardItem(b[3])] for item in b: barri.append(QStandardItem(item)) dist[0].appendRow(barri) ultimaDistr = int(b[0]) return True except: print("Error en construcció de l'arbre de zones") return False # def llegirDistrictesBarrisCSV(self): # try: # first = True # with open(self.__distBarrisCSV, newline='') as csvFile: # reader = csv.DictReader(csvFile, delimiter=';') # root = self.model.invisibleRootItem() # for row in reader: # if first: # Primer registro # self.labels = ['ZONA'] # for item in row: # self.labels.append(item) # self.model.setColumnCount(len(self.labels)) # self.model.setHorizontalHeaderLabels(self.labels) # first = False # if row['BARRI'] == '': # Registro de distrito # dist = [QStandardItem(row['NOM_DISTRICTE'])] # for item in row.values(): # dist.append(QStandardItem(item)) # root.appendRow(dist) # else: # Registro de barrio # barri = [QStandardItem(row['NOM_BARRI'])] # for item in row.values(): # barri.append(QStandardItem(item)) # dist[0].appendRow(barri) # return True # except: # print('QDistrictesBarris.llegirDistrictesBarrisCSV(): ', sys.exc_info()[0], sys.exc_info()[1]) # return False def llegirRegistre(self): try: click = self.view.currentIndex() #Controlarem si s'ha canviat d'índex o no if hasattr(self, 'ultimIndex') and self.ultimIndex == click: return self.registre self.ultimIndex = click self.registre = {} for i in range(self.model.columnCount()): index = click.sibling(click.row(), i) item = self.model.itemFromIndex(index) self.registre[self.labels[i]] = item.text() self.registre['RANG'] = QgsRectangle(float(self.registre['X_MIN']), \ float(self.registre['Y_MIN']), \ float(self.registre['X_MAX']), \ float(self.registre['Y_MAX'])) except: print('QDistrictesBarris.llegirRegistre(): ', sys.exc_info()[0], sys.exc_info()[1]) finally: return self.registre def llegirRang(self): return self.llegirRegistre()['RANG'] def esDistricte(self): return self.llegirRegistre()['BARRI'] == '' def esBarri(self): return not self.esDistricte() def llegirNom(self): if self.esDistricte(): distr = self.llegirRegistre()["NOM_DISTRICTE"] distr_d = distr + "_d" return distr_d else: barri = self.llegirRegistre()["NOM_BARRI"] if barri == "Barcelona": return barri else: barri_b = barri + "_b" return barri_b def llegirID(self): if self.esDistricte(): return self.llegirRegistre()['DISTRICTE'] return self.llegirRegistre()['BARRI']
class AdjustmentDialogThresholds(QObject): COLOR_ERROR = QColor(224, 103, 103) COLOR_ATTENTION = QColor(237, 148, 76) COLOR_NEUTRAL = QColor(255, 255, 255) COLOR = {1: COLOR_NEUTRAL, 2: COLOR_ATTENTION, 3: COLOR_ERROR} sig_clickedRow = pyqtSignal(int) def __init__(self, parent, datasetSize): """ :type parent: gui.adjustmentDialog.AdjustmentDialog """ super().__init__() self.parent = parent self.tbl = self.parent.tableThresholds self.model = QStandardItemModel(datasetSize[0], datasetSize[1], self.tbl) self.initState = True self.thresholdExeeded = False self.tbl.setModel(self.model) self.tbl.resizeColumnsToContents() self.tbl.resizeRowsToContents() # Icons self.iconOk = QIcon() self.iconOk.addPixmap( QPixmap(":/plugins/SeilaplanPlugin/gui/icons/icon_green.png"), QIcon.Normal, QIcon.Off) self.iconErr = QIcon() self.iconErr.addPixmap( QPixmap( ":/plugins/SeilaplanPlugin/gui/icons/icon_exclamation.png"), QIcon.Normal, QIcon.Off) self.tbl.clicked.connect(self.onClick) def populate(self, header, dataset, valueColumn): self.model.setHorizontalHeaderLabels(header) self.tbl.hideColumn(5) # Insert data into cells for i, rowData in enumerate(dataset): for j, cellData in enumerate(rowData): if j == 0: # Create clickable info button in first column btnWidget = self.createInfoBtn(cellData) self.tbl.setIndexWidget(self.model.index(i, j), btnWidget) continue if j == 5 and isinstance(cellData, dict): loclen = len(cellData['loc']) if loclen > 0: # Set background color for cells where threshold is # exceeded color = self.COLOR[max(cellData['color'] or [1])] self.colorBackground(i, valueColumn, color) cellData = loclen item = QStandardItem(cellData) self.model.setItem(i, j, item) self.model.setData(self.model.index(i, j), cellData) # Adjust column widths self.tbl.resizeColumnsToContents() for idx in range(2, self.model.columnCount()): currSize = self.tbl.sizeHintForColumn(idx) self.tbl.setColumnWidth(idx, max(currSize, 100)) self.tbl.setFocusPolicy(Qt.NoFocus) self.updateTabIcon() def updateData(self, row, col, newVal): # Update background color of new values if col == 5 and isinstance(newVal, dict): locLen = len(newVal['loc']) color = self.COLOR[max(newVal['color'] or [1])] self.colorBackground(row, 4, color) newVal = locLen # Update value itself self.model.setData(self.model.index(row, col), newVal) self.updateTabIcon() # Remove the background color from initially calculated # cable line data if self.initState: self.initState = False for row in range(self.model.rowCount()): self.colorBackground(row, 3, self.COLOR_NEUTRAL) def colorBackground(self, row, col, color): self.model.setData(self.model.index(row, col), QBrush(color), Qt.BackgroundRole) def updateTabIcon(self): """ Updates icon of QTabWidget with an exclamation mark or check mark depending on presents of exceeded thresholds.""" thresholdExceeded = False for i in range(0, self.model.rowCount()): if i == 2: # Dont check thresholds for 'Sattelkraft' continue data = self.model.data(self.model.index(i, 5)) if data and data > 0: thresholdExceeded = True break if thresholdExceeded: self.parent.tabWidget.setTabIcon(2, self.iconErr) else: self.parent.tabWidget.setTabIcon(2, self.iconOk) def onClick(self, item): # Row is already selected if self.parent.selectedThdRow == item.row(): # Deselect self.tbl.clearSelection() # Emit select signal self.sig_clickedRow.emit(item.row()) def createInfoBtn(self, cellData): button = QPushButton('?') button.setMaximumSize(QSize(22, 22)) # Fill info text into message box button.clicked.connect( lambda: QMessageBox.information(self.parent, cellData[ 'title'], cellData['message'], QMessageBox.Ok)) cellWidget = QWidget() # Add layout to center button in cell layout = QHBoxLayout(cellWidget) layout.addWidget(button, 0, Qt.AlignCenter) layout.setAlignment(Qt.AlignCenter) cellWidget.setLayout(layout) return cellWidget