def __init__(self, finders, iface, parent=None): self.iface = iface self.mapCanvas = iface.mapCanvas() self.marker = None self.rubber = QgsRubberBand(self.mapCanvas) self.rubber.setColor(QColor(255, 255, 50, 200)) self.rubber.setIcon(self.rubber.ICON_CIRCLE) self.rubber.setIconSize(15) self.rubber.setWidth(4) self.rubber.setBrushStyle(Qt.NoBrush) QComboBox.__init__(self, parent) self.setEditable(True) self.setInsertPolicy(QComboBox.InsertAtTop) self.setMinimumHeight(27) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.insertSeparator(0) self.lineEdit().returnPressed.connect(self.search) self.result_view = QTreeView() self.result_view.setHeaderHidden(True) self.result_view.setMinimumHeight(300) self.result_view.activated.connect(self.itemActivated) self.result_view.pressed.connect(self.itemPressed) self.setView(self.result_view) self.result_model = ResultModel(self) self.setModel(self.result_model) self.finders = finders for finder in list(self.finders.values()): finder.result_found.connect(self.result_found) finder.limit_reached.connect(self.limit_reached) finder.finished.connect(self.finished) self.clearButton = QPushButton(self) self.clearButton.setIcon( QIcon(":/plugins/quickfinder/icons/draft.svg")) self.clearButton.setText('') self.clearButton.setFlat(True) self.clearButton.setCursor(QCursor(Qt.ArrowCursor)) self.clearButton.setStyleSheet('border: 0px; padding: 0px;') self.clearButton.clicked.connect(self.clear) layout = QHBoxLayout(self) self.setLayout(layout) layout.addStretch() layout.addWidget(self.clearButton) layout.addSpacing(20) button_size = self.clearButton.sizeHint() # frameWidth = self.lineEdit().style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth) padding = button_size.width() # + frameWidth + 1 self.lineEdit().setStyleSheet('QLineEdit {padding-right: %dpx; }' % padding)
def event(self, event: QEvent) -> bool: if event.type() == QEvent.Leave: if self._iface: self.clear_footprint() event.accept() return QTreeView.event(self, event)
def __init__(self, parent: QWidget = None): super().__init__(parent) self.setMinimumSize(750, 500) #Layout principal. Tot aquí self.layout = QVBoxLayout(self) #Layout de la capçalera self.layoutCapcalera = QHBoxLayout() self.lblTitol = QLabel(' Documentació') self.layoutCapcalera.addWidget(self.lblTitol) self.qModel = ElMeuModel(self) self.lblExplicacio = QLabel() if os.path.isdir(carpetaDocuments): self.lblExplicacio.setText( 'Esteu visualitzant la documentació corporativa completa') rootPath = self.qModel.setRootPath(carpetaDocuments) else: self.lblExplicacio.setText( 'No teniu accés a la documentació corporativa. Esteu visualitzant una còpia local que pot no estar actualitzada.' ) rootPath = self.qModel.setRootPath(carpetaDocumentsLocal) self.treeView = QTreeView(self) self.treeView.setModel(self.qModel) self.treeView.setRootIndex(rootPath) self.treeView.clicked.connect(self.clicat) self.treeView.doubleClicked.connect(self.obrir) self.layoutBotonera = QHBoxLayout() self.layoutBotonera.addStretch() self.botoObrir = QvPushButton('Obrir', destacat=True) self.botoObrir.setEnabled(False) self.botoObrir.clicked.connect(self.obrir) self.layoutBotonera.addWidget(self.botoObrir) self.botoDescarregar = QvPushButton('Descarregar') self.botoDescarregar.setEnabled(False) self.botoDescarregar.clicked.connect(self.desar) self.layoutBotonera.addWidget(self.botoDescarregar) self.botoSortir = QvPushButton('Sortir') self.botoSortir.clicked.connect(self.close) self.layoutBotonera.addWidget(self.botoSortir) self.layout.addLayout(self.layoutCapcalera) self.layout.addWidget(self.lblExplicacio) self.layout.addWidget(self.treeView) self.layout.addLayout(self.layoutBotonera) self.formata()
def __init__(self, mainWindow): QTreeView.__init__(self, mainWindow) self.mainWindow = mainWindow self.setModel(DBModel(self)) self.setHeaderHidden(True) self.setEditTriggers(QTreeView.EditKeyPressed | QTreeView.SelectedClicked) self.setDragEnabled(True) self.setAcceptDrops(True) self.setDropIndicatorShown(True) self.doubleClicked.connect(self.addLayer) self.selectionModel().currentChanged.connect(self.currentItemChanged) self.expanded.connect(self.itemChanged) self.collapsed.connect(self.itemChanged) self.model().dataChanged.connect(self.modelDataChanged) self.model().notPopulated.connect(self.collapse)
def mousePressEvent(self, event: QMouseEvent) -> None: index = self.indexAt(event.pos()) sel_model: QItemSelectionModel = self.selectionModel() if (index.column() == 1 and event.button() == Qt.LeftButton and sel_model.isSelected(index)): log.debug('Ignoring mouse press') return return QTreeView.mousePressEvent(self, event)
def keyReleaseEvent(self, event: QKeyEvent) -> None: index = self.currentIndex() if (index.column() == 0 and event.key() in [Qt.Key_Enter, Qt.Key_Return]): node: PlanetNode = self.model().get_node(index) if (node.node_type() == NodeT.LOAD_MORE and node.parent() == self.model().root): self.model().fetch_more_top_items(index) return QTreeView.keyReleaseEvent(self, event)
def mouseReleaseEvent(self, event: QMouseEvent) -> None: index = self.indexAt(event.pos()) sel_model: QItemSelectionModel = self.selectionModel() if (index.column() == 1 and event.button() == Qt.LeftButton and sel_model.isSelected(index)): log.debug('Swapping left button for right, on release') self.open_menu(event.pos()) return return QTreeView.mouseReleaseEvent(self, event)
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 __init__(self, canvas, pare=None): """[summary] Arguments: canvas {[QgsMapCanvas]} -- [El canvas que es vol gestionar] """ self.pare = pare self.canvas = canvas QWidget.__init__(self) # Leemos un fichero serializado para cargar sus ubicaciones en data try: with open(fic_guardar_arbre, 'rb') as fga: data = pickle.load(fga) fga.close() except: data = [] # Instanciamos ARBOL ************************************************************+***** self.arbre = QTreeView() # Ponemos menu contextual l arbol self.arbre.setContextMenuPolicy(Qt.ActionsContextMenu) self.actEsborrar = QAction("Esborrar branca", self) self.actEsborrar.setStatusTip("Esborrar") self.actEsborrar.triggered.connect(self.esborrarNode) self.arbre.addAction(self.actEsborrar) self.actExpand = QAction("Expandeix/Contreu Tot", self) self.actExpand.setStatusTip("Expand") self.actExpand.triggered.connect(self.expand_all) self.arbre.addAction(self.actExpand) self.actClear = QAction("Esborrar arbre", self) self.actClear.setStatusTip("Clear") self.actClear.triggered.connect(self.clear_all) self.arbre.addAction(self.actClear) # Permitimos arrastre de ramas en arbol self.arbre.setDragDropMode( QAbstractItemView.InternalMove) # 4atencion internal # Amaguem (o no) les capçaleres. False és que no s'amaguen. # self.arbre.setHeaderHidden(True) #aqui # self.arbre.setColumnWidth(0,8000) # self.arbre.setHorizontalScrollBarPolicy(1) self.arbre.clicked.connect(self._clickArbre) # Fem visible l'arbre self.arbre.show() # Instanciamos MODELO ********************************************************************* self.model = StandardItemModel_mio(data, ubicacions=self) # asignamos al arbol el modelo self.arbre.setModel(self.model) #Amaguem totes les columnes menys la primera for i in range(self.model.columnCount()): if i != 0: self.arbre.setColumnHidden( i, False ) # atencion, si oculto columnas no puedo ver coordenadas de los hijos # Connectem el click de l'arbre a la funció _clickArbre # no_se self.selectionModel = self.arbre.selectionModel() # Cal un invisibleRootItem qu eés la arrel del arbre d'on penjen els elements de la base. self.arrelModel = self.model.invisibleRootItem() # Definim els labels del arbre. self.labels = ['Ubicació', 'xMin', 'yMin', 'xMax', 'yMax', 'Projecte'] # En funció d'aquests labels s'estableix el numero de columnes que tindrà el model (i l'arbre) self.model.setColumnCount(len(self.labels)) # Coloquem els labels com a headers del model (i l'arbre) self.model.setHorizontalHeaderLabels(self.labels) # ELEMENTOS GRAFICOS DE LA CLASE # Definim un lineEdit, li afegim un tooltip i el connectem a una funció quan es premi Return self.leUbicacions = QLineEdit() self.leUbicacions.setToolTip( 'Escriu el nom de la ubicació i prem Return') self.leUbicacions.returnPressed.connect(self._novaUbicacio) #Definimos un boton para guardar las ubicaciones icon = QIcon() fichero = './imatges/guardar.png' icon.addPixmap(QPixmap(fichero)) # icon.addPixmap(QPixmap("D:/projectes_py/qVista/imatges/guardar.png")) # self.boton_1 = QPushButton(icon,'') # self.boton_1.setToolTip("Desar ubicacions") # self.boton_1.setMaximumSize(QSize(20,20)) # self.boton_1.show() # self.boton_1.clicked.connect(self.model.exportData) self.lblubicacio = QLabel('Ubicació:') # Creamos un caja de diseño vertical que s'aplica al widget QvUbicacions self.layVUbicacions = QVBoxLayout(self) # Creamos una caja de diseño horizontal self.layHUbicacions = QHBoxLayout() # incluimos en la caja horizontal el line edit y el boton (entran de izquierda a derecha) self.layHUbicacions.addWidget(self.lblubicacio) self.layHUbicacions.addWidget(self.leUbicacions) # self.layHUbicacions.addWidget(self.boton_1) # y colocacion en contenidor horizontal # incluimos en caja vertical el la caja horizontal y el arbol (entran desde abajo) self.layVUbicacions.addLayout(self.layHUbicacions) self.layVUbicacions.addWidget(self.arbre) # Podriem afegir un frame (fBotonera), sobre el que carregar botons # self.layUbicacions.addWidget(self.fBotonera) # PARA QUE HAGA CASO HA DE PONERSE ESTAS LINEAS POST .SETMODEL self.arbre.setHeaderHidden(True) #aqui self.arbre.setColumnWidth(0, 8000) self.arbre.setHorizontalScrollBarPolicy(1)
def on_copy(self): self.ds_model.sort(DSManagerModel.COLUMN_GROUP_DS) select_data_sources_dialog = QDialog(self) select_data_sources_dialog.resize(400, 400) select_data_sources_dialog.setWindowTitle( self.tr("Choose source service")) layout = QVBoxLayout(select_data_sources_dialog) select_data_sources_dialog.setLayout(layout) list_view = QTreeView(self) layout.addWidget(list_view) list_view.setModel(self.ds_model) #list_view.expandAll() list_view.setColumnHidden(DSManagerModel.COLUMN_VISIBILITY, True) list_view.setAlternatingRowColors(True) if hasattr(list_view.header(), "setResizeMode"): # Qt4 list_view.header().setResizeMode(DSManagerModel.COLUMN_GROUP_DS, QHeaderView.ResizeToContents) else: # Qt5 list_view.header().setSectionResizeMode( DSManagerModel.COLUMN_GROUP_DS, QHeaderView.ResizeToContents) list_view.clicked.connect( lambda index: select_data_sources_dialog.accept() \ if not self.ds_model.isGroup(index) and \ index.column() == DSManagerModel.COLUMN_GROUP_DS \ else None ) if select_data_sources_dialog.exec_() == QDialog.Accepted: data_source = self.ds_model.data(list_view.currentIndex(), Qt.UserRole) data_source.id += "_copy" edit_dialog = DsEditDialog() edit_dialog.setWindowTitle(self.tr('Create service from existing')) edit_dialog.fill_ds_info(data_source) if edit_dialog.exec_() == QDialog.Accepted: self.feel_list() self.ds_model.resetModel()
def __init__(self, parent=None): QTreeView.__init__(self, parent) self.setItemDelegate(VariablesDelegate(self))
def on_copy(self): self.ds_model.sort(DSManagerModel.COLUMN_GROUP_DS) select_data_sources_dialog = QDialog(self) select_data_sources_dialog.resize(400, 400) select_data_sources_dialog.setWindowTitle(self.tr("Choose source service")) layout = QVBoxLayout(select_data_sources_dialog) select_data_sources_dialog.setLayout(layout) list_view = QTreeView(self) layout.addWidget(list_view) list_view.setModel(self.ds_model) #list_view.expandAll() list_view.setColumnHidden(DSManagerModel.COLUMN_VISIBILITY, True) list_view.setAlternatingRowColors(True) if hasattr(list_view.header(), "setResizeMode"): # Qt4 list_view.header().setResizeMode(DSManagerModel.COLUMN_GROUP_DS, QHeaderView.ResizeToContents) else: # Qt5 list_view.header().setSectionResizeMode(DSManagerModel.COLUMN_GROUP_DS, QHeaderView.ResizeToContents) list_view.clicked.connect( lambda index: select_data_sources_dialog.accept() \ if not self.ds_model.isGroup(index) and \ index.column() == DSManagerModel.COLUMN_GROUP_DS \ else None ) if select_data_sources_dialog.exec_() == QDialog.Accepted: data_source = self.ds_model.data(list_view.currentIndex(), Qt.UserRole) data_source.id += "_copy" edit_dialog = DsEditDialog() edit_dialog.setWindowTitle(self.tr('Create service from existing')) edit_dialog.fill_ds_info(data_source) if edit_dialog.exec_() == QDialog.Accepted: self.feel_list() self.ds_model.resetModel()
class FinderBox(QComboBox): running = False to_finish = 0 search_started = pyqtSignal() search_finished = pyqtSignal() def __init__(self, finders, iface, parent=None): self.iface = iface self.mapCanvas = iface.mapCanvas() self.marker = None self.rubber = QgsRubberBand(self.mapCanvas) self.rubber.setColor(QColor(255, 255, 50, 200)) self.rubber.setIcon(self.rubber.ICON_CIRCLE) self.rubber.setIconSize(15) self.rubber.setWidth(4) self.rubber.setBrushStyle(Qt.NoBrush) QComboBox.__init__(self, parent) self.setEditable(True) self.setInsertPolicy(QComboBox.InsertAtTop) self.setMinimumHeight(27) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.insertSeparator(0) self.lineEdit().returnPressed.connect(self.search) self.result_view = QTreeView() self.result_view.setHeaderHidden(True) self.result_view.setMinimumHeight(300) self.result_view.activated.connect(self.itemActivated) self.result_view.pressed.connect(self.itemPressed) self.setView(self.result_view) self.result_model = ResultModel(self) self.setModel(self.result_model) self.finders = finders for finder in list(self.finders.values()): finder.result_found.connect(self.result_found) finder.limit_reached.connect(self.limit_reached) finder.finished.connect(self.finished) self.clearButton = QPushButton(self) self.clearButton.setIcon( QIcon(":/plugins/quickfinder/icons/draft.svg")) self.clearButton.setText('') self.clearButton.setFlat(True) self.clearButton.setCursor(QCursor(Qt.ArrowCursor)) self.clearButton.setStyleSheet('border: 0px; padding: 0px;') self.clearButton.clicked.connect(self.clear) layout = QHBoxLayout(self) self.setLayout(layout) layout.addStretch() layout.addWidget(self.clearButton) layout.addSpacing(20) button_size = self.clearButton.sizeHint() # frameWidth = self.lineEdit().style().pixelMetric(QtGui.QStyle.PM_DefaultFrameWidth) padding = button_size.width() # + frameWidth + 1 self.lineEdit().setStyleSheet('QLineEdit {padding-right: %dpx; }' % padding) def __del__(self): if self.rubber: self.iface.mapCanvas().scene().removeItem(self.rubber) del self.rubber #clear marker that the lonlat seted def clearMarker(self): self.mapCanvas.scene().removeItem(self.marker) self.marker = None def clearSelection(self): self.result_model.setSelected(None, self.result_view.palette()) self.rubber.reset() #self.clearMarker() def clear(self): self.clearSelection() self.result_model.clearResults() self.lineEdit().setText('') def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.clearSelection() self.clearMarker() QComboBox.keyPressEvent(self, event) def lnglatFinder(self, to_find): import re m = re.match(r'(?P<lon>-?\d*(.\d+))\s+(?P<lat>-?\d*(.\d+))', to_find) if not m: return False x = float(m.group('lon')) y = float(m.group('lat')) return self.zoomLnglat(x, y) def zoomLnglat(self, lng, lat): x, y = lng, lat canvas = self.mapCanvas currExt = canvas.extent() canvasCenter = currExt.center() dx = float(x) - canvasCenter.x() dy = float(y) - canvasCenter.y() xMin = currExt.xMinimum() + dx xMax = currExt.xMaximum() + dx yMin = currExt.yMinimum() + dy yMax = currExt.yMaximum() + dy rect = QgsRectangle(xMin, yMin, xMax, yMax) canvas.setExtent(rect) pt = QgsPointXY(float(x), float(y)) self.marker = QgsVertexMarker(canvas) self.marker.setCenter(pt) self.marker.setIconSize(18) self.marker.setPenWidth(2) self.marker.setIconType(QgsVertexMarker.ICON_CROSS) canvas.refresh() return True # def geocodeFinder(self, to_finder): # print(to_finder[:2]) # if not to_finder[:2] == 'b:': # return False # # address = to_finder[2:] # url = MySettings().value("baiduUrl") # url = url + parse.quote(address) # # response = request.urlopen(url) # content = response.read() # data = json.loads(content) # print(data) # lng, lat = (data['result']['location']['lng'], data['result']['location']['lat']) # from .cood_trans import bd09_to_wgs84 # lng, lat = bd09_to_wgs84(lng, lat) # print(f'{lng}-{lat}') # return self.zoomLnglat(lng, lat) def search(self): # self.geocode() if self.running: return to_find = self.lineEdit().text() if not to_find or to_find == '': return # if not (self.lnglatFinder(to_find) or self.geocodeFinder(to_find)): if not self.lnglatFinder(to_find): self.showPopup() self.running = True self.search_started.emit() self.clearSelection() self.result_model.clearResults() self.result_model.truncateHistory(MySettings().value("historyLength")) self.result_model.setLoading(True) QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.finders_to_start = [] for finder in list(self.finders.values()): if finder.activated(): self.finders_to_start.append(finder) bbox = self.mapCanvas.fullExtent() while len(self.finders_to_start) > 0: finder = self.finders_to_start[0] self.finders_to_start.remove(finder) self.result_model.addResult(finder.name) finder.start(to_find, bbox=bbox) # For case there is no finder activated self.finished(None) def stop(self): self.finders_to_start = [] for finder in list(self.finders.values()): if finder.is_running(): finder.stop() self.finished(None) def result_found(self, finder, layername, value, geometry, srid): self.result_model.addResult(finder.name, layername, value, geometry, srid) self.result_view.expandAll() def limit_reached(self, finder, layername): self.result_model.addEllipsys(finder.name, layername) def finished(self, finder): if len(self.finders_to_start) > 0: return for finder in list(self.finders.values()): if finder.is_running(): return self.running = False self.search_finished.emit() self.result_model.setLoading(False) QCoreApplication.processEvents(QEventLoop.ExcludeUserInputEvents) def itemActivated(self, index): item = self.result_model.itemFromIndex(index) self.showItem(item) def itemPressed(self, index): item = self.result_model.itemFromIndex(index) if QApplication.mouseButtons() == Qt.LeftButton: self.showItem(item) def showItem(self, item): if isinstance(item, ResultItem): self.result_model.setSelected(item, self.result_view.palette()) geometry = self.transform_geom(item) self.rubber.reset(geometry.type()) self.rubber.setToGeometry(geometry, None) self.zoom_to_rubberband() return if isinstance(item, GroupItem): child = item.child(0) if isinstance(child, ResultItem): self.result_model.setSelected(item, self.result_view.palette()) self.rubber.reset(child.geometry.type()) for i in range(0, item.rowCount()): geometry = self.transform_geom(item.child(i)) self.rubber.addGeometry(geometry, None) self.zoom_to_rubberband() return if item.__class__.__name__ == 'QStandardItem': self.clearSelection() def transform_geom(self, item): src_crs = QgsCoordinateReferenceSystem() src_crs.createFromSrid(item.srid) dest_crs = self.mapCanvas.mapSettings().destinationCrs() geom = QgsGeometry(item.geometry) geom.transform( QgsCoordinateTransform(src_crs, dest_crs, QgsProject.instance())) return geom def zoom_to_rubberband(self): geom = self.rubber.asGeometry() if geom: rect = geom.boundingBox() rect.scale(1.5) self.mapCanvas.setExtent(rect) self.mapCanvas.refresh()
def __init__(self, parent=None): QTreeView.__init__(self, parent) self.setRootIsDecorated(False)
class QvUbicacions(QWidget): """Una classe del tipus QWidget que mostra i gestiona un arbre d'ubicacions. Poden afegir-se noves ubicacions i guardar-hi una descripció. Un click sobre una ubicació ens situa en el rang guardat previament. """ def __init__(self, canvas, pare=None): """[summary] Arguments: canvas {[QgsMapCanvas]} -- [El canvas que es vol gestionar] """ self.pare = pare self.canvas = canvas QWidget.__init__(self) # Leemos un fichero serializado para cargar sus ubicaciones en data try: with open(fic_guardar_arbre, 'rb') as fga: data = pickle.load(fga) fga.close() except: data = [] # Instanciamos ARBOL ************************************************************+***** self.arbre = QTreeView() # Ponemos menu contextual l arbol self.arbre.setContextMenuPolicy(Qt.ActionsContextMenu) self.actEsborrar = QAction("Esborrar branca", self) self.actEsborrar.setStatusTip("Esborrar") self.actEsborrar.triggered.connect(self.esborrarNode) self.arbre.addAction(self.actEsborrar) self.actExpand = QAction("Expandeix/Contreu Tot", self) self.actExpand.setStatusTip("Expand") self.actExpand.triggered.connect(self.expand_all) self.arbre.addAction(self.actExpand) self.actClear = QAction("Esborrar arbre", self) self.actClear.setStatusTip("Clear") self.actClear.triggered.connect(self.clear_all) self.arbre.addAction(self.actClear) # Permitimos arrastre de ramas en arbol self.arbre.setDragDropMode( QAbstractItemView.InternalMove) # 4atencion internal # Amaguem (o no) les capçaleres. False és que no s'amaguen. # self.arbre.setHeaderHidden(True) #aqui # self.arbre.setColumnWidth(0,8000) # self.arbre.setHorizontalScrollBarPolicy(1) self.arbre.clicked.connect(self._clickArbre) # Fem visible l'arbre self.arbre.show() # Instanciamos MODELO ********************************************************************* self.model = StandardItemModel_mio(data, ubicacions=self) # asignamos al arbol el modelo self.arbre.setModel(self.model) #Amaguem totes les columnes menys la primera for i in range(self.model.columnCount()): if i != 0: self.arbre.setColumnHidden( i, False ) # atencion, si oculto columnas no puedo ver coordenadas de los hijos # Connectem el click de l'arbre a la funció _clickArbre # no_se self.selectionModel = self.arbre.selectionModel() # Cal un invisibleRootItem qu eés la arrel del arbre d'on penjen els elements de la base. self.arrelModel = self.model.invisibleRootItem() # Definim els labels del arbre. self.labels = ['Ubicació', 'xMin', 'yMin', 'xMax', 'yMax', 'Projecte'] # En funció d'aquests labels s'estableix el numero de columnes que tindrà el model (i l'arbre) self.model.setColumnCount(len(self.labels)) # Coloquem els labels com a headers del model (i l'arbre) self.model.setHorizontalHeaderLabels(self.labels) # ELEMENTOS GRAFICOS DE LA CLASE # Definim un lineEdit, li afegim un tooltip i el connectem a una funció quan es premi Return self.leUbicacions = QLineEdit() self.leUbicacions.setToolTip( 'Escriu el nom de la ubicació i prem Return') self.leUbicacions.returnPressed.connect(self._novaUbicacio) #Definimos un boton para guardar las ubicaciones icon = QIcon() fichero = './imatges/guardar.png' icon.addPixmap(QPixmap(fichero)) # icon.addPixmap(QPixmap("D:/projectes_py/qVista/imatges/guardar.png")) # self.boton_1 = QPushButton(icon,'') # self.boton_1.setToolTip("Desar ubicacions") # self.boton_1.setMaximumSize(QSize(20,20)) # self.boton_1.show() # self.boton_1.clicked.connect(self.model.exportData) self.lblubicacio = QLabel('Ubicació:') # Creamos un caja de diseño vertical que s'aplica al widget QvUbicacions self.layVUbicacions = QVBoxLayout(self) # Creamos una caja de diseño horizontal self.layHUbicacions = QHBoxLayout() # incluimos en la caja horizontal el line edit y el boton (entran de izquierda a derecha) self.layHUbicacions.addWidget(self.lblubicacio) self.layHUbicacions.addWidget(self.leUbicacions) # self.layHUbicacions.addWidget(self.boton_1) # y colocacion en contenidor horizontal # incluimos en caja vertical el la caja horizontal y el arbol (entran desde abajo) self.layVUbicacions.addLayout(self.layHUbicacions) self.layVUbicacions.addWidget(self.arbre) # Podriem afegir un frame (fBotonera), sobre el que carregar botons # self.layUbicacions.addWidget(self.fBotonera) # PARA QUE HAGA CASO HA DE PONERSE ESTAS LINEAS POST .SETMODEL self.arbre.setHeaderHidden(True) #aqui self.arbre.setColumnWidth(0, 8000) self.arbre.setHorizontalScrollBarPolicy(1) def ubicacionsFi(self): self.model.exportData() def esborrarNode(self): """ Eliminar rama del arbol """ self.model.removeRow(self.arbre.currentIndex().row(), self.arbre.currentIndex().parent()) def expand_all(self): """Expandir o contraer todo el arbol, dependiendo de si detecta que esta extendido o contraido """ if self.arbre.isExpanded(self.model.index(0, 0, QModelIndex())): self.arbre.collapseAll() else: self.arbre.expandAll() def clear_all(self): """ Eliminar el arbol completo """ self.model.removeRows(0, self.model.rowCount()) self.model.setRowCount(0) def _novaUbicacio(self): """Es dona d'alta una ubicació al arbre. """ # Treiem el focus del lineEdit self.leUbicacions.clearFocus() # El text descriptiu de la ubicació entrat al lineEdit descripcioUbicacio = self.leUbicacions.text() # Llegim les coordenades màximes i mínimes a partir del rang del canvas rang = self.canvas.extent() xmax = int(rang.xMaximum()) ymax = int(rang.yMaximum()) xmin = int(rang.xMinimum()) ymin = int(rang.yMinimum()) # Només donem l'alta la ubicació si en tenim una descripció if descripcioUbicacio == '': pass else: # filaItems contindrà objectes del tipus QStandarItem per a carregar-los al model filaItems = [] # Construim la llista d'elements que formen la ubicació itemsFila = [ descripcioUbicacio, xmin, ymin, xmax, ymax, QgsProject().instance().fileName() ] # Convertim la llista d'elements a llista de QStandarItem's, construint filaItems. for item in itemsFila: item_Qs = QStandardItem(str(item)) item_Qs.setToolTip('') filaItems.append(item_Qs) #Añadir en raiz try: self.arrelModel.appendRow(filaItems) except: pass self.leUbicacions.clear() # try: # self.model.exportData() # except Exception as ee: # print(str(ee)) def _clickArbre(self): """Es gestiona el dobleclick sobre una ubicació. El canvas gestionat es visualitzarà segons el rang de la ubicació. """ # La següent linia carrega les variables de x,y màximes i mínimes, segons el currentIndex del model clickat. try: xxmin = float( self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 0 + 1)).text()) yymin = float( self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 1 + 1)).text()) xxmax = float( self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 2 + 1)).text()) yymax = float( self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 3 + 1)).text()) # self.model.itemFromIndex(self.arbre.currentIndex().sibling(0, 0)).text() para debugar contenidos # Construim un rang del tipus QgsRectangle # rang = QgsRectangle(xmin, ymin, xmax, ymax) rang = QgsRectangle(xxmin, yymin, xxmax, yymax) # Canviem l'extensió del canvas segons el rang recien calculat. self.canvas.zoomToFeatureExtent(rang) if self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 0)).text()[0] == chr(45): # "-" : if self.model.itemFromIndex(self.arbre.currentIndex().sibling( self.arbre.currentIndex().row(), 0)).text()[1] == chr(62): #">" : self.canvas.scene().removeItem(self.pare.marcaLloc) self.pare.marcaLloc = QgsVertexMarker(self.pare.canvas) self.pare.marcaLloc.setCenter( QgsPointXY(float((xxmin + xxmax) / 2), float((yymin + yymax) / 2))) self.pare.marcaLloc.setColor(QColor(255, 0, 0)) self.pare.marcaLloc.setIconSize(15) self.pare.marcaLloc.setIconType( QgsVertexMarker.ICON_CIRCLE ) # or ICON_NONE, ICON_CROSS, ICON_X, ICON_BOX, ICON_CIRCLE, ICON_DOUBLE_TRIANGLE self.pare.marcaLloc.setPenWidth(3) self.pare.marcaLloc.show() self.pare.marcaLlocPosada = True except: pass def _prepararBotonera(self): #??? """Funció reservada per a la gestió de la botonera de ubicacions. En aquest moment no s'utilitza. """ self.botoneraArbre = ['Nou'] for text in self.botoneraArbre: boto = QtWidgets.QPushButton() boto.setText(text) boto.setMaximumWidth(50) boto.clicked.connect(self.novaUbicacio) self.layBotonera.addWidget(boto) self.fBotonera.show() spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.layBotonera.addSpacerItem(spacer)
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 QvDocumentacio(QDialog): comencaCarrega = pyqtSignal() acabaCarrega = pyqtSignal() '''Diàleg que mostra la documentació de la carpeta de documentació definida a configuracioQvista Mostra una TreeView amb els documents, i delega en el sistema la tasca d'obrir-los''' def __init__(self, parent: QWidget = None): super().__init__(parent) self.setMinimumSize(750, 500) #Layout principal. Tot aquí self.layout = QVBoxLayout(self) #Layout de la capçalera self.layoutCapcalera = QHBoxLayout() self.lblTitol = QLabel(' Documentació') self.layoutCapcalera.addWidget(self.lblTitol) self.qModel = ElMeuModel(self) self.lblExplicacio = QLabel() if os.path.isdir(carpetaDocuments): self.lblExplicacio.setText( 'Esteu visualitzant la documentació corporativa completa') rootPath = self.qModel.setRootPath(carpetaDocuments) else: self.lblExplicacio.setText( 'No teniu accés a la documentació corporativa. Esteu visualitzant una còpia local que pot no estar actualitzada.' ) rootPath = self.qModel.setRootPath(carpetaDocumentsLocal) self.treeView = QTreeView(self) self.treeView.setModel(self.qModel) self.treeView.setRootIndex(rootPath) self.treeView.clicked.connect(self.clicat) self.treeView.doubleClicked.connect(self.obrir) self.layoutBotonera = QHBoxLayout() self.layoutBotonera.addStretch() self.botoObrir = QvPushButton('Obrir', destacat=True) self.botoObrir.setEnabled(False) self.botoObrir.clicked.connect(self.obrir) self.layoutBotonera.addWidget(self.botoObrir) self.botoDescarregar = QvPushButton('Descarregar') self.botoDescarregar.setEnabled(False) self.botoDescarregar.clicked.connect(self.desar) self.layoutBotonera.addWidget(self.botoDescarregar) self.botoSortir = QvPushButton('Sortir') self.botoSortir.clicked.connect(self.close) self.layoutBotonera.addWidget(self.botoSortir) self.layout.addLayout(self.layoutCapcalera) self.layout.addWidget(self.lblExplicacio) self.layout.addWidget(self.treeView) self.layout.addLayout(self.layoutBotonera) self.formata() def formata(self): self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint) self.layout.setAlignment(Qt.AlignCenter) self.lblTitol.setStyleSheet( 'background-color: %s; color: %s; border: 0px' % (QvConstants.COLORFOSCHTML, QvConstants.COLORBLANCHTML)) self.lblTitol.setFont(QvConstants.FONTCAPCALERES) self.lblTitol.setFixedHeight(40) self.lblExplicacio.setWordWrap(True) self.lblExplicacio.setStyleSheet( f'color: {QvConstants.COLORFOSCHTML}; margin: 20px 20px 0px 20px') for i in range(1, 4): self.treeView.header().hideSection(i) self.treeView.setHeaderHidden(True) self.treeView.adjustSize() self.treeView.setAnimated(True) self.treeView.setStyleSheet( 'QTreeView{margin: 20px 2px 0px 20px; border: none;}') self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.layoutBotonera.setContentsMargins(10, 10, 10, 10) def clicat(self, index: int): path = self.qModel.fileInfo(index).absoluteFilePath() self.index = index if os.path.isfile(path): self.botoObrir.setEnabled(True) self.botoDescarregar.setEnabled(True) else: self.botoObrir.setEnabled(False) self.botoDescarregar.setEnabled(True) def obrir(self): path = self.qModel.fileInfo(self.index).absoluteFilePath() if os.path.isfile(path): self.comencaCarrega.emit() if '.html' in path: self.visor = QvVisorHTML(path, 'Vídeo de documentació') self.visor.setZoomFactor(1) self.visor.show() else: os.startfile(path) time.sleep(1) self.acabaCarrega.emit() def desar(self): path = self.qModel.fileInfo(self.index).absoluteFilePath() if os.path.isfile(path): nfile, _ = QFileDialog.getSaveFileName( None, 'Desar arxiu', os.path.join(QvMemoria().getDirectoriDesar(), Path(path).name)) if nfile != '': shutil.copy(path, nfile) else: nomCarpeta = Path(path).name nfile = str( QFileDialog.getExistingDirectory(self, "Select Directory")) if nfile != '': shutil.copytree(path, os.path.join(nfile, nomCarpeta)) def mousePressEvent(self, event): self.oldPos = event.globalPos() def mouseMoveEvent(self, event): delta = QPoint(event.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = event.globalPos() def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.close() if event.key() == Qt.Key_Return: self.obrir()