| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- from PyQt5.QtGui import QTextOption
- from PyQt5.uic.properties import QtWidgets
- from qgis.PyQt.QtWidgets import QDialog, QVBoxLayout, QTabWidget, QTableWidget, QTableWidgetItem, QGraphicsView, \
- QGraphicsScene, QPushButton
- from qgis.core import QgsProject, QgsVectorLayer
- from qgis.gui import QgsMapCanvas
- from qgis.utils import iface
- from qgis.PyQt.QtGui import QColor
- from PyQt5.QtWidgets import QSizePolicy, QStyledItemDelegate
- from PyQt5.QtCore import Qt, QSizeF, QRectF
- class WordWrapDelegate(QStyledItemDelegate):
- def paint(self, painter, option, index):
- if index.column() == 1: # Only apply word wrapping to the second column
- painter.save()
- # Create a QRectF for the bounding box (the cell's rectangle)
- rect = QRectF(option.rect) # Use option.rect for the cell's bounding rectangle
- # Define the QTextOption for word wrapping
- text_option = QTextOption()
- text_option.setWrapMode(QTextOption.WrapMode.WordWrap) # Enable word wrap
- # Draw the text inside the cell with word wrapping
- painter.setClipRect(option.rect) # Set clipping to the cell's rectangle
- painter.drawText(rect, index.data(), text_option) # Correct method signature here
- painter.restore()
- else:
- super().paint(painter, option, index)
- class CombinedDialog(QDialog):
- def __init__(self, layer, parent=None):
- super().__init__(parent)
- self.layer = layer
- # Set the dialog layout
- self.setWindowTitle('图层属性')
- layout = QVBoxLayout(self)
- # Create a QTabWidget to hold the different panels
- self.tabs = QTabWidget(self)
- # Add Metadata Panel (using QTableWidget instead of QTextEdit)
- metadata_table = QTableWidget(self) # Create a table widget for displaying metadata
- self.populate_metadata_table(metadata_table) # Populate the table with metadata
- self.tabs.addTab(metadata_table, '基本信息')
- # Add Preview Panel (using QgsMapCanvas in a QGraphicsView)
- preview_widget = QGraphicsView(self)
- preview_scene = QGraphicsScene(self)
- preview_widget.setScene(preview_scene)
- # Set up the map canvas for previewing the layer
- map_canvas = QgsMapCanvas()
- map_canvas.setCanvasColor(QColor('white')) # Set the canvas color to white
- map_canvas.setDestinationCrs(self.layer.crs()) # Set the CRS of the map canvas
- map_canvas.setExtent(self.layer.extent()) # Set the extent to match the layer's extent
- map_canvas.setLayers([self.layer]) # Set the layer to be previewed
- map_canvas.refresh() # Refresh the map canvas to show the layer
- # Add the map canvas to the preview scene
- preview_scene.addWidget(map_canvas)
- # Make sure the preview widget expands to fill the layout
- preview_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- # preview_scene.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- self.tabs.addTab(preview_widget, '预览')
- # Add Attribute Table Button
- if isinstance(layer, QgsVectorLayer):
- self.show_attribute_table_button = QPushButton("属性表", self)
- self.show_attribute_table_button.setFixedSize(60, 25)
- self.show_attribute_table_button.clicked.connect(self.show_attribute_table)
- layout.addWidget(self.show_attribute_table_button)
- # Add the QTabWidget to the layout
- layout.addWidget(self.tabs)
- # Set dialog size
- self.resize(800, 600)
- # Ensure the map canvas resizes to fit inside the scene
- map_canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
- # Connect the resize event to adjust the canvas size
- preview_widget.resizeEvent = self.on_resize_event
- def on_resize_event(self, event):
- """Handles the resize event to ensure the map canvas adjusts its size."""
- # Resize the map canvas to the size of the QGraphicsView
- preview_widget = self.findChild(QGraphicsView)
- map_canvas = preview_widget.scene().items()[0] # Get the map canvas from the scene
- # Convert QSize to QSizeF (float size)
- new_size = QSizeF(preview_widget.size().width(), preview_widget.size().height())
- # Resize the canvas to match the new size
- map_canvas.resize(new_size) # Resize with QSizeF
- event.accept()
- def populate_metadata_table(self, table_widget):
- """Populate the table with metadata information of the layer."""
- # Get layer metadata
- metadata = [
- ("图层名称", self.layer.name()),
- # ("Layer Type", str(self.layer.type())),
- ("坐标系", self.layer.crs().authid()),
- ]
- if isinstance(self.layer, QgsVectorLayer):
- metadata.append(("要素数量", str(self.layer.featureCount())))
- metadata.append(("字段", ", ".join([field.name() for field in self.layer.fields()])))
- metadata.append(("数据范围", str(self.layer.extent().toString())))
- # Set the table dimensions
- table_widget.setRowCount(len(metadata))
- table_widget.setColumnCount(2)
- # Set the table headers
- table_widget.setHorizontalHeaderLabels(["属性名称", "属性值"])
- # Hide the headers
- table_widget.horizontalHeader().setVisible(False) # Hide horizontal (column) headers
- table_widget.verticalHeader().setVisible(False) # Optionally hide vertical (row) headers
- # Set column width
- table_widget.setColumnWidth(0, 200) # Set the first column (attribute) to a fixed width of 200px
- table_widget.setColumnWidth(1, 600)
- # Make the second column (value) stretchable
- # table_widget.horizontalHeader().setSectionResizeMode(1)
- # Populate the table with the metadata
- for row, (attribute, value) in enumerate(metadata):
- item_attr = QTableWidgetItem(attribute)
- item_value = QTableWidgetItem(value)
- # Enable word wrapping for both columns
- item_attr.setTextAlignment(Qt.AlignCenter | Qt.AlignLeft)
- item_value.setTextAlignment(Qt.AlignCenter | Qt.AlignLeft)
- # Wrap text in the second column (value)
- text_option = QTextOption()
- text_option.setWrapMode(QTextOption.WrapMode.WordWrap) # Enable word wrap for this column
- item_value.setText(value) # Apply value with word wrap option
- # Add items to the table
- table_widget.setItem(row, 0, item_attr)
- table_widget.setItem(row, 1, item_value)
- delegate = WordWrapDelegate()
- table_widget.setItemDelegateForColumn(1, delegate)
- table_widget.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
- table_widget.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
- # Resize the columns to fit the content
- table_widget.resizeColumnsToContents()
- table_widget.resizeColumnToContents(1)
- def get_layer_metadata(self, layer):
- """Return basic metadata information of the layer"""
- metadata = []
- # Get layer name
- metadata.append(f"Layer Name: {layer.name()}")
- # Get layer type
- metadata.append(f"Layer Type: {layer.type()}")
- # Get CRS (Coordinate Reference System)
- metadata.append(f"CRS: {layer.crs().authid()}")
- # Get feature count
- if isinstance(layer, QgsVectorLayer):
- metadata.append(f"Feature Count: {layer.featureCount()}")
- # Get fields (attribute names)
- fields = ", ".join([field.name() for field in layer.fields()])
- metadata.append(f"Fields: {fields}")
- # Get extent
- metadata.append(f"Extent: {layer.extent().toString()}")
- return "\n".join(metadata)
- def show_attribute_table(self):
- """Show the attribute table for the current layer"""
- # Ensure the attribute table is brought to the front
- # Bring the main window and attribute table dialog to the front
- main_window = iface.mainWindow()
- main_window.raise_() # Raise the main window to the front
- main_window.activateWindow() # Focus the main window
- # Additionally, ensure the active window is focused (in case the attribute table dialog gets hidden)
- iface.showAttributeTable(self.layer) # Reopen if needed to ensure focus
- def showDialog(self):
- self.exec_()
- # Usage:
- # layer = iface.activeLayer() # Get the active layer
- # if layer:
- # dialog = CombinedDialog(layer)
- # dialog.showDialog()
- # else:
- # print("No layer selected")
|