Пример #1
0
class DataFrameModel(QAbstractTableModel):
    """Podstawowy model tabeli zasilany przez pandas dataframe."""
    DtypeRole = Qt.UserRole + 1000
    ValueRole = Qt.UserRole + 1001

    def __init__(self, df=pd.DataFrame(), tv=None, col_names=[], parent=None):
        super(DataFrameModel, self).__init__(parent)
        self._dataframe = df
        self.col_names = col_names
        self.tv = tv  # Referencja do tableview
        self.tv.setModel(self)
        self.tv.selectionModel().selectionChanged.connect(
            lambda: self.layoutChanged.emit())
        self.tv.horizontalHeader().setSortIndicatorShown(False)
        self.sort_col = -1
        self.sort_ord = 1

    def col_names(self, df, col_names):
        """Nadanie nazw kolumn tableview'u."""
        df.columns = col_names
        return df

    def sort_reset(self):
        """Wyłącza sortowanie po kolumnie."""
        self.sort_col = -1
        self.sort_ord = 1

    def setDataFrame(self, dataframe):
        self.beginResetModel()
        self._dataframe = dataframe.copy()
        self.endResetModel()

    def dataFrame(self):
        return self._dataframe

    dataFrame = pyqtProperty(pd.DataFrame, fget=dataFrame, fset=setDataFrame)

    @pyqtSlot(int, Qt.Orientation, result=str)
    def headerData(self,
                   section: int,
                   orientation: Qt.Orientation,
                   role: int = Qt.DisplayRole):
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal:
                if self.col_names:
                    try:
                        return self.col_names[section]  # type: ignore
                    except:
                        pass
                return self._dataframe.columns[section]
            else:
                return str(self._dataframe.index[section])
        return QVariant()
        # if role == Qt.DecorationRole and orientation == Qt.Horizontal:
        #     self.tv.setSortIndicatorShown(False)

    def rowCount(self, parent=QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._dataframe.index)

    def columnCount(self, parent=QModelIndex()):
        if parent.isValid():
            return 0
        return self._dataframe.columns.size

    def data(self, index, role=Qt.DisplayRole):
        if not index.isValid() or not (0 <= index.row() < self.rowCount() \
            and 0 <= index.column() < self.columnCount()):
            return QVariant()
        row = self._dataframe.index[index.row()]
        col = self._dataframe.columns[index.column()]
        dt = self._dataframe[col].dtype
        try:
            val = self._dataframe.iloc[row][col]
        except:
            return QVariant()
        # if role == Qt.DisplayRole:
        # #     # Get the raw value
        # #     if isinstance(val, float) and (index.column() == 2 or index.column() == 3):
        # #         return "%.2f" % val
        # #     if isinstance(val, float) and (index.column() == 4 or index.column() == 5):
        # #         return "%.1f" % val
        # #     if isinstance(val, float) & index.column() == 6:
        # #         return "%.0f" % val
        #     return str(val)
        if role == DataFrameModel.ValueRole:
            return val
        if role == DataFrameModel.DtypeRole:
            return dt
        return QVariant()

    def roleNames(self):
        roles = {
            Qt.DisplayRole: b'display',
            DataFrameModel.DtypeRole: b'dtype',
            DataFrameModel.ValueRole: b'value'
        }
        return roles
Пример #2
0
class GdalToolsInOutSelector(QWidget, Ui_GdalToolsInOutSelector):
    FILE = 0x1
    LAYER = 0x2
    MULTIFILE = 0x4    # NOT IMPLEMENTED YET

    FILE_LAYER = 0x1 | 0x2
    FILES = 0x1 | 0x4    # NOT IMPLEMENTED YET
    FILES_LAYER = 0x3 | 0x4    # NOT IMPLEMENTED YET

    selectClicked = pyqtSignal()
    filenameChanged = pyqtSignal()
    layerChanged = pyqtSignal()

    def __init__(self, parent=None, type=None):
        QWidget.__init__(self, parent)

        self.setupUi(self)
        self.setFocusPolicy(Qt.StrongFocus)
        self.combo.setInsertPolicy(QComboBox.NoInsert)

        self.clear()

        self.typ = None
        if type is None:
            self.resetType()
        else:
            self.setType(type)

        self.selectBtn.clicked.connect(self.selectClicked)
        self.fileEdit.textChanged.connect(self.textChanged)
        self.combo.editTextChanged.connect(self.textChanged)
        self.combo.currentIndexChanged.connect(self.indexChanged)

    def clear(self):
        self.filenames = []
        self.fileEdit.clear()
        self.clearComboState()
        self.combo.clear()

    def textChanged(self):
        if self.getType() & self.MULTIFILE:
            self.filenames = self.fileEdit.text().split(",")
        if self.getType() & self.LAYER:
            index = self.combo.currentIndex()
            if index >= 0:
                text = self.combo.currentText()
                if text != self.combo.itemText(index):
                    return self.setFilename(text)
        self.filenameChanged.emit()

    def indexChanged(self):
        self.layerChanged.emit()
        self.filenameChanged.emit()

    def setType(self, type):
        if type == self.typ:
            return

        if type & self.MULTIFILE:    # MULTITYPE IS NOT IMPLEMENTED YET
            type = type & ~self.MULTIFILE

        self.typ = type

        self.selectBtn.setVisible(self.getType() & self.FILE)
        self.combo.setVisible(self.getType() & self.LAYER)
        self.fileEdit.setVisible(not (self.getType() & self.LAYER))
        self.combo.setEditable(self.getType() & self.FILE)

        if self.getType() & self.FILE:
            self.setFocusProxy(self.selectBtn)
        else:
            self.setFocusProxy(self.combo)

        # send signals to refresh connected widgets
        self.filenameChanged.emit()
        self.layerChanged.emit()

    def getType(self):
        return self.typ

    def resetType(self):
        self.setType(self.FILE_LAYER)

    selectorType = pyqtProperty("int", getType, setType, resetType)

    def setFilename(self, fn=None):
        self.blockSignals(True)
        prevFn, prevLayer = self.filename(), self.layer()

        if isinstance(fn, QgsMapLayer):
            fn = fn.source()

        elif isinstance(fn, str) or isinstance(fn, str):
            fn = str(fn)

        # TODO test
        elif isinstance(fn, list):
            if len(fn) > 0:
                if self.getType() & self.MULTIFILE:
                    self.filenames = fn
                #fn = "".join( fn, "," )
                fn = ",".join(fn)
            else:
                fn = ''

        else:
            fn = ''

        if not (self.getType() & self.LAYER):
            self.fileEdit.setText(fn)
        else:
            self.combo.setCurrentIndex(-1)
            self.combo.setEditText(fn)

        self.blockSignals(False)
        if self.filename() != prevFn:
            self.filenameChanged.emit()
        if self.layer() != prevLayer:
            self.layerChanged.emit()

    def setLayer(self, layer=None):
        if not (self.getType() & self.LAYER):
            return self.setFilename(layer)

        self.blockSignals(True)
        prevFn, prevLayer = self.filename(), self.layer()

        if isinstance(layer, QgsMapLayer):
            if self.combo.findData(layer.id()) >= 0:
                index = self.combo.findData(layer.id())
                self.combo.setCurrentIndex(index)
            else:
                self.combo.setCurrentIndex(-1)
                self.combo.setEditText(layer.source())

        elif isinstance(layer, int) and layer >= 0 and layer < self.combo.count():
            self.combo.setCurrentIndex(layer)

        else:
            self.combo.clearEditText()
            self.combo.setCurrentIndex(-1)

        self.blockSignals(False)
        if self.filename() != prevFn:
            self.filenameChanged.emit()
        if self.layer() != prevLayer:
            self.layerChanged.emit()

    def setLayers(self, layers=None):
        if layers is None or not hasattr(layers, '__iter__') or len(layers) <= 0:
            self.combo.clear()
            return

        self.blockSignals(True)
        prevFn, prevLayer = self.filename(), self.layer()
        self.saveComboState()

        self.combo.clear()
        for l in layers:
            self.combo.addItem(l.name(), l.id())

        self.restoreComboState()
        self.blockSignals(False)
        if self.filename() != prevFn:
            self.filenameChanged.emit()
        if self.layer() != prevLayer:
            self.layerChanged.emit()

    def clearComboState(self):
        self.prevState = None

    def saveComboState(self):
        index = self.combo.currentIndex()
        text = self.combo.currentText()
        layerID = self.combo.itemData(index) if index >= 0 else ""
        self.prevState = (index, text, layerID)

    def restoreComboState(self):
        if self.prevState is None:
            return
        index, text, layerID = self.prevState

        if index < 0:
            if text == '' and self.combo.count() > 0:
                index = 0

        elif self.combo.findData(layerID) < 0:
            index = -1
            text = ""

        else:
            index = self.combo.findData(layerID)

        self.combo.setCurrentIndex(index)
        if index >= 0:
            text = self.combo.itemText(index)
        self.combo.setEditText(text)

    def layer(self):
        if self.getType() != self.FILE and self.combo.currentIndex() >= 0:
            layerID = self.combo.itemData(self.combo.currentIndex())
            return QgsMapLayerRegistry.instance().mapLayer(layerID)
        return None

    def filename(self):
        if not (self.getType() & self.LAYER):
            if self.getType() & self.MULTIFILE:
                return self.filenames
            return self.fileEdit.text()

        if self.combo.currentIndex() < 0:
            if self.getType() & self.MULTIFILE:
                return self.filenames
            return self.combo.currentText()
        layer = self.layer()
        if layer is not None:
            return layer.source()

        return ''
Пример #3
0
class CompassWidget(QWidget):

    angleChanged = pyqtSignal(float)
    angle2Changed = pyqtSignal(float)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self._angle = -9999.9
        self._angle2 = -9999.9
        self._margins = 10
        self._pointText = {
            0: "N",
            45: "45",
            90: "90",
            135: "135",
            180: "S",
            225: "225",
            270: "270",
            315: "315"
        }

    def paintEvent(self, event):
        painter = QPainter()
        painter.begin(self)
        painter.setRenderHint(QPainter.Antialiasing)

        painter.fillRect(event.rect(), self.palette().brush(QPalette.Window))
        self.drawMarkings(painter)
        self.drawNeedle(painter)
        self.drawNeedle2(painter)
        painter.end()

    def drawMarkings(self, painter):
        painter.save()
        painter.translate(self.width() / 2, self.height() / 2)
        scale = min((self.width() - self._margins) / 120.0,
                    (self.height() - self._margins) / 120.0)
        painter.scale(scale, scale)

        font = QFont(self.font())
        font.setPixelSize(10)
        metrics = QFontMetricsF(font)

        painter.setFont(font)
        painter.setPen(self.palette().color(QPalette.Shadow))

        i = 0
        while i < 360:
            if i % 45 == 0:
                painter.drawLine(0, -40, 0, -50)
                painter.drawText(int(-metrics.width(self._pointText[i]) / 2),
                                 -52, self._pointText[i])
            else:
                painter.drawLine(0, -45, 0, -50)
            painter.rotate(15)
            i += 15
        painter.restore()

    def drawNeedle(self, painter):
        if self._angle < -9999:
            return
        painter.save()
        painter.translate(self.width() / 2, self.height() / 2)
        painter.rotate(self._angle)
        scale = min((self.width() - self._margins) / 120.0,
                    (self.height() - self._margins) / 120.0)
        painter.scale(scale, scale)

        painter.setPen(QPen(Qt.NoPen))
        #         painter.setBrush(self.palette().brush(QPalette.Shadow))
        #
        #         painter.drawPolygon(
        #             QPolygon([QPoint(-10, 0), QPoint(0, -45), QPoint(10, 0),
        #                       QPoint(0, 45), QPoint(-10, 0)])
        #             )

        painter.setBrush(self.palette().brush(QPalette.Highlight))

        painter.drawPolygon(
            QPolygon([
                QPoint(-5, -25),
                QPoint(0, -45),
                QPoint(5, -25),
                QPoint(0, -30),
                QPoint(-5, -25)
            ]))

        painter.restore()

    def drawNeedle2(self, painter):
        if self._angle2 < -9999:
            return
        painter.save()
        painter.translate(self.width() / 2, self.height() / 2)
        painter.rotate(self._angle2)
        scale = min((self.width() - self._margins) / 120.0,
                    (self.height() - self._margins) / 120.0)
        painter.scale(scale, scale)

        painter.setPen(QPen(Qt.NoPen))
        #         painter.setBrush(self.palette().brush(QPalette.Dark))
        #
        #         painter.drawPolygon(
        #             QPolygon([QPoint(-7, 0), QPoint(0, -25), QPoint(7, 0),
        #                       QPoint(0, 25), QPoint(-7, 0)])
        #             )

        painter.setBrush(self.palette().brush(QPalette.Foreground))

        painter.drawPolygon(
            QPolygon([
                QPoint(-5, -10),
                QPoint(0, -25),
                QPoint(5, -10),
                QPoint(0, -13),
                QPoint(-5, -10)
            ]))

        painter.restore()

    def sizeHint(self):
        return QSize(150, 150)

    def angle(self):
        return self._angle

    def angle2(self):
        return self._angle2

    @pyqtSlot(float)
    def setAngle(self, angle):
        if angle != self._angle:
            self._angle = angle
            self.angleChanged.emit(angle)
            self.update()

    angle = pyqtProperty(float, angle, setAngle)

    @pyqtSlot(float)
    def setAngle2(self, angle):
        if angle != self._angle2:
            self._angle2 = angle
            self.angle2Changed.emit(angle)
            self.update()

    angle2 = pyqtProperty(float, angle2, setAngle2)

    def reset(self, no=None):
        if no == 1:
            self._angle = -9999.9
        elif no == 2:
            self._angle2 = -9999.9
        else:
            self._angle = -9999.9
            self._angle2 = -9999.9
        self.update()